19#pragma convert("ISO8859-1")
39#ifdef LIBXML_XPTR_LOCS_ENABLED
42#ifdef LIBXML_DEBUG_ENABLED
48#ifdef LIBXML_PATTERN_ENABLED
54#ifdef LIBXML_PATTERN_ENABLED
55#define XPATH_STREAMING
59 xmlGenericError(xmlGenericErrorContext, \
60 "Unimplemented block at %s:%d\n", \
81#define XP_OPTIMIZED_NON_ELEM_COMPARISON
88#define XP_OPTIMIZED_FILTER_FIRST
104#define XPATH_MAX_STEPS 1000000
113#define XPATH_MAX_STACK_DEPTH 1000000
123#define XPATH_MAX_NODESET_LENGTH 10000000
130#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
131#define XPATH_MAX_RECURSION_DEPTH 500
133#define XPATH_MAX_RECURSION_DEPTH 5000
143#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
158 int misc = 0, precedence1 = 0, precedence2 = 0;
163 if ((node1 ==
NULL) || (node2 ==
NULL))
172 switch (node1->
type) {
177 (node1->
doc == node2->
doc))
186 goto turtle_comparison;
243 switch (node2->
type) {
289 if (node1 == node2) {
290 if (precedence1 == precedence2) {
295 cur = miscNode2->prev;
297 if (
cur == miscNode1)
310 if (precedence1 < precedence2)
325 if ((precedence2 == 3) && (precedence1 > 1)) {
333 if ((precedence1 == 3) && (precedence2 > 1)) {
350 (node1->
doc == node2->
doc)) {
362 if (node1 == node2->
prev)
364 if (node1 == node2->
next)
370 if (
cur->parent == node1)
376 if (
cur->parent == node2)
389 while (depth1 > depth2) {
393 while (depth2 > depth1) {
401 if ((node1 ==
NULL) || (node2 ==
NULL))
407 if (node1 == node2->
prev)
409 if (node1 == node2->
next)
418 (node1->
doc == node2->
doc)) {
439#define SORT_NAME libxml_domnode
440#define SORT_TYPE xmlNodePtr
453#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
462 int res = xmlXPathCmpNodes(
x,
y);
466#define SORT_CMP(x, y) (wrap_cmp(x, y))
470#if defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
478double xmlXPathNAN = 0.0;
479double xmlXPathPINF = 0.0;
480double xmlXPathNINF = 0.0;
493#if defined(NAN) && defined(INFINITY)
500 xmlXPathNAN = 0.0 /
zero;
501 xmlXPathPINF = 1.0 /
zero;
502 xmlXPathNINF = -xmlXPathPINF;
513xmlXPathIsNaN(
double val) {
528xmlXPathIsInf(
double val) {
532 if (
val >= xmlXPathPINF)
534 if (
val <= -xmlXPathPINF)
542#ifdef LIBXML_XPATH_ENABLED
548#ifdef DEBUG_XPATH_EXPRESSION
551#define DEBUG_EVAL_COUNTS
554static xmlNs xmlXPathXMLNamespaceStruct = {
562static xmlNsPtr xmlXPathXMLNamespace = &xmlXPathXMLNamespaceStruct;
563#ifndef LIBXML_THREAD_ENABLED
568static int xmlXPathDisableOptimizer = 0;
583#define XP_ERRORNULL(X) \
584 { xmlXPathErr(ctxt, X); return(NULL); }
589static const char*
const xmlXPathErrorMessages[] = {
592 "Unfinished literal\n",
593 "Start of literal\n",
594 "Expected $ for variable reference\n",
595 "Undefined variable\n",
596 "Invalid predicate\n",
597 "Invalid expression\n",
598 "Missing closing curly brace\n",
599 "Unregistered function\n",
602 "Invalid number of arguments\n",
603 "Invalid context size\n",
604 "Invalid context position\n",
605 "Memory allocation error\n",
608 "Sub resource error\n",
609 "Undefined namespace prefix\n",
611 "Char out of XML range\n",
612 "Invalid or incomplete context\n",
613 "Stack usage error\n",
614 "Forbidden variable\n",
615 "Operation limit exceeded\n",
616 "Recursion limit exceeded\n",
617 "?? Unknown error ??\n"
619#define MAXERRNO ((int)(sizeof(xmlXPathErrorMessages) / \
620 sizeof(xmlXPathErrorMessages[0])) - 1)
629xmlXPathErrMemory(xmlXPathContextPtr ctxt,
const char *
extra)
637 "Memory allocation failed : %s\n",
641 ctxt->lastError.message = (
char *)
646 if (ctxt->error !=
NULL)
647 ctxt->error(ctxt->userData, &ctxt->lastError);
654 "Memory allocation failed : %s\n",
extra);
660 "Memory allocation failed\n");
672xmlXPathPErrMemory(xmlXPathParserContextPtr ctxt,
const char *
extra)
677 ctxt->error = XPATH_MEMORY_ERROR;
678 xmlXPathErrMemory(ctxt->context,
extra);
690xmlXPathErr(xmlXPathParserContextPtr ctxt,
int error)
700 "%s", xmlXPathErrorMessages[
error]);
704 if (ctxt->context ==
NULL) {
709 (
const char *) ctxt->base,
NULL,
NULL,
710 ctxt->cur - ctxt->base, 0,
711 "%s", xmlXPathErrorMessages[
error]);
722 ctxt->context->lastError.str1 = (
char *)
xmlStrdup(ctxt->base);
723 ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
724 ctxt->context->lastError.node = ctxt->context->debugNode;
725 if (ctxt->context->error !=
NULL) {
726 ctxt->context->error(ctxt->context->userData,
727 &ctxt->context->lastError);
733 (
const char *) ctxt->base,
NULL,
NULL,
734 ctxt->cur - ctxt->base, 0,
735 "%s", xmlXPathErrorMessages[
error]);
752 xmlXPathErr(ctxt,
no);
764xmlXPathCheckOpLimit(xmlXPathParserContextPtr ctxt,
unsigned long opCount) {
765 xmlXPathContextPtr xpctxt = ctxt->context;
767 if ((opCount > xpctxt->opLimit) ||
768 (xpctxt->opCount > xpctxt->opLimit - opCount)) {
769 xpctxt->opCount = xpctxt->opLimit;
770 xmlXPathErr(ctxt, XPATH_OP_LIMIT_EXCEEDED);
774 xpctxt->opCount += opCount;
778#define OP_LIMIT_EXCEEDED(ctxt, n) \
779 ((ctxt->context->opLimit != 0) && (xmlXPathCheckOpLimit(ctxt, n) < 0))
792typedef struct _xmlPointerList xmlPointerList;
793typedef xmlPointerList *xmlPointerListPtr;
794struct _xmlPointerList {
804xmlPointerListAddSize(xmlPointerListPtr
list,
809 if (initialSize <= 0)
811 list->items = (
void **)
xmlMalloc(initialSize *
sizeof(
void *));
813 xmlXPathErrMemory(
NULL,
814 "xmlPointerListCreate: allocating item\n");
821 xmlXPathErrMemory(
NULL,
822 "xmlPointerListAddSize: re-allocating item\n");
829 xmlXPathErrMemory(
NULL,
830 "xmlPointerListAddSize: re-allocating item\n");
846static xmlPointerListPtr
847xmlPointerListCreate(
int initialSize)
849 xmlPointerListPtr
ret;
853 xmlXPathErrMemory(
NULL,
854 "xmlPointerListCreate: allocating item\n");
858 if (initialSize > 0) {
859 xmlPointerListAddSize(
ret,
NULL, initialSize);
872xmlPointerListFree(xmlPointerListPtr
list)
910#ifdef LIBXML_XPTR_LOCS_ENABLED
917 AXIS_ANCESTOR_OR_SELF,
921 AXIS_DESCENDANT_OR_SELF,
923 AXIS_FOLLOWING_SIBLING,
927 AXIS_PRECEDING_SIBLING,
947typedef struct _xmlXPathStepOp xmlXPathStepOp;
948typedef xmlXPathStepOp *xmlXPathStepOpPtr;
949struct _xmlXPathStepOp {
958 xmlXPathFunction
cache;
962struct _xmlXPathCompExpr {
965 xmlXPathStepOp *
steps;
969#ifdef DEBUG_EVAL_COUNTS
973#ifdef XPATH_STREAMING
984xmlXPathFreeValueTree(xmlNodeSetPtr
obj);
986xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
obj);
988xmlXPathCompOpEvalFirst(xmlXPathParserContextPtr ctxt,
991xmlXPathCompOpEvalToBoolean(xmlXPathParserContextPtr ctxt,
992 xmlXPathStepOpPtr
op,
1010static xmlXPathCompExprPtr
1011xmlXPathNewCompExpr(
void) {
1012 xmlXPathCompExprPtr
cur;
1014 cur = (xmlXPathCompExprPtr)
xmlMalloc(
sizeof(xmlXPathCompExpr));
1016 xmlXPathErrMemory(
NULL,
"allocating component\n");
1019 memset(
cur, 0,
sizeof(xmlXPathCompExpr));
1023 sizeof(xmlXPathStepOp));
1025 xmlXPathErrMemory(
NULL,
"allocating steps\n");
1029 memset(
cur->steps, 0,
cur->maxStep *
sizeof(xmlXPathStepOp));
1031#ifdef DEBUG_EVAL_COUNTS
1044xmlXPathFreeCompExpr(xmlXPathCompExprPtr comp)
1046 xmlXPathStepOpPtr
op;
1051 if (comp->dict ==
NULL) {
1052 for (
i = 0;
i < comp->nbStep;
i++) {
1053 op = &comp->steps[
i];
1054 if (
op->value4 !=
NULL) {
1055 if (
op->op == XPATH_OP_VALUE)
1056 xmlXPathFreeObject(
op->value4);
1064 for (
i = 0;
i < comp->nbStep;
i++) {
1065 op = &comp->steps[
i];
1066 if (
op->value4 !=
NULL) {
1067 if (
op->op == XPATH_OP_VALUE)
1068 xmlXPathFreeObject(
op->value4);
1073 if (comp->steps !=
NULL) {
1076#ifdef DEBUG_EVAL_COUNTS
1077 if (comp->string !=
NULL) {
1081#ifdef XPATH_STREAMING
1082 if (comp->stream !=
NULL) {
1083 xmlFreePatternList(comp->stream);
1086 if (comp->expr !=
NULL) {
1110xmlXPathCompExprAdd(xmlXPathParserContextPtr ctxt,
int ch1,
int ch2,
1112 int value2,
int value3,
void *value4,
void *value5) {
1113 xmlXPathCompExprPtr comp = ctxt->comp;
1114 if (comp->nbStep >= comp->maxStep) {
1115 xmlXPathStepOp *
real;
1118 xmlXPathPErrMemory(ctxt,
"adding step\n");
1123 comp->maxStep *
sizeof(xmlXPathStepOp));
1126 xmlXPathPErrMemory(ctxt,
"adding step\n");
1131 comp->last = comp->nbStep;
1132 comp->steps[comp->nbStep].ch1 = ch1;
1133 comp->steps[comp->nbStep].ch2 = ch2;
1134 comp->steps[comp->nbStep].op =
op;
1135 comp->steps[comp->nbStep].value =
value;
1136 comp->steps[comp->nbStep].value2 = value2;
1137 comp->steps[comp->nbStep].value3 = value3;
1138 if ((comp->dict !=
NULL) &&
1139 ((
op == XPATH_OP_FUNCTION) || (
op == XPATH_OP_VARIABLE) ||
1140 (
op == XPATH_OP_COLLECT))) {
1141 if (value4 !=
NULL) {
1142 comp->steps[comp->nbStep].value4 = (
xmlChar *)
1146 comp->steps[comp->nbStep].value4 =
NULL;
1147 if (value5 !=
NULL) {
1148 comp->steps[comp->nbStep].value5 = (
xmlChar *)
1152 comp->steps[comp->nbStep].value5 =
NULL;
1154 comp->steps[comp->nbStep].value4 = value4;
1155 comp->steps[comp->nbStep].value5 = value5;
1157 comp->steps[comp->nbStep].cache =
NULL;
1158 return(comp->nbStep++);
1169xmlXPathCompSwap(xmlXPathStepOpPtr
op) {
1172#ifndef LIBXML_THREAD_ENABLED
1178 if (xmlXPathDisableOptimizer)
1187#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5) \
1188 xmlXPathCompExprAdd(ctxt, (op1), (op2), \
1189 (op), (val), (val2), (val3), (val4), (val5))
1190#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5) \
1191 xmlXPathCompExprAdd(ctxt, ctxt->comp->last, -1, \
1192 (op), (val), (val2), (val3), (val4), (val5))
1194#define PUSH_LEAVE_EXPR(op, val, val2) \
1195xmlXPathCompExprAdd(ctxt, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
1197#define PUSH_UNARY_EXPR(op, ch, val, val2) \
1198xmlXPathCompExprAdd(ctxt, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
1200#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) \
1201xmlXPathCompExprAdd(ctxt, (ch1), (ch2), (op), \
1202 (val), (val2), 0 ,NULL ,NULL)
1212#define XP_HAS_CACHE(c) ((c != NULL) && ((c)->cache != NULL))
1214typedef struct _xmlXPathContextCache xmlXPathContextCache;
1215typedef xmlXPathContextCache *xmlXPathContextCachePtr;
1216struct _xmlXPathContextCache {
1217 xmlPointerListPtr nodesetObjs;
1218 xmlPointerListPtr stringObjs;
1219 xmlPointerListPtr booleanObjs;
1220 xmlPointerListPtr numberObjs;
1221 xmlPointerListPtr miscObjs;
1227#ifdef XP_DEBUG_OBJ_USAGE
1229 int dbgCachedNodeset;
1230 int dbgCachedString;
1232 int dbgCachedNumber;
1235 int dbgCachedLocset;
1237 int dbgCachedXSLTTree;
1238 int dbgCachedUndefined;
1242 int dbgReusedNodeset;
1243 int dbgReusedString;
1245 int dbgReusedNumber;
1248 int dbgReusedLocset;
1250 int dbgReusedXSLTTree;
1251 int dbgReusedUndefined;
1263 xmlGenericError(xmlGenericErrorContext, \
1264 "Internal error at %s:%d\n", \
1265 __FILE__, __LINE__);
1267#ifdef LIBXML_DEBUG_ENABLED
1273 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1278 fprintf(output,
"Node is NULL !\n");
1290 xmlDebugDumpOneNode(output,
cur,
depth);
1298 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1303 fprintf(output,
"Node is NULL !\n");
1311 xmlDebugDumpOneNode(output, tmp,
depth);
1316xmlXPathDebugDumpNodeSet(
FILE *output, xmlNodeSetPtr
cur,
int depth) {
1320 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1326 fprintf(output,
"NodeSet is NULL !\n");
1332 fprintf(output,
"Set contains %d nodes:\n",
cur->nodeNr);
1333 for (
i = 0;
i <
cur->nodeNr;
i++) {
1336 xmlXPathDebugDumpNode(output,
cur->nodeTab[
i],
depth + 1);
1342xmlXPathDebugDumpValueTree(
FILE *output, xmlNodeSetPtr
cur,
int depth) {
1346 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1352 fprintf(output,
"Value Tree is NULL !\n");
1359 xmlXPathDebugDumpNodeList(output,
cur->nodeTab[0]->children,
depth + 1);
1361#if defined(LIBXML_XPTR_LOCS_ENABLED)
1363xmlXPathDebugDumpLocationSet(
FILE *output, xmlLocationSetPtr
cur,
int depth) {
1367 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1373 fprintf(output,
"LocationSet is NULL !\n");
1378 for (
i = 0;
i <
cur->locNr;
i++) {
1381 xmlXPathDebugDumpObject(output,
cur->locTab[
i],
depth + 1);
1395xmlXPathDebugDumpObject(
FILE *output, xmlXPathObjectPtr
cur,
int depth) {
1399 if (output ==
NULL)
return;
1401 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1409 fprintf(output,
"Object is empty (NULL)\n");
1413 case XPATH_UNDEFINED:
1414 fprintf(output,
"Object is uninitialized\n");
1417 fprintf(output,
"Object is a Node Set :\n");
1418 xmlXPathDebugDumpNodeSet(output,
cur->nodesetval,
depth);
1420 case XPATH_XSLT_TREE:
1421 fprintf(output,
"Object is an XSLT value tree :\n");
1422 xmlXPathDebugDumpValueTree(output,
cur->nodesetval,
depth);
1425 fprintf(output,
"Object is a Boolean : ");
1427 else fprintf(output,
"false\n");
1430 switch (xmlXPathIsInf(
cur->floatval)) {
1432 fprintf(output,
"Object is a number : Infinity\n");
1435 fprintf(output,
"Object is a number : -Infinity\n");
1438 if (xmlXPathIsNaN(
cur->floatval)) {
1439 fprintf(output,
"Object is a number : NaN\n");
1440 }
else if (
cur->floatval == 0) {
1442 fprintf(output,
"Object is a number : 0\n");
1444 fprintf(output,
"Object is a number : %0g\n",
cur->floatval);
1449 fprintf(output,
"Object is a string : ");
1450 xmlDebugDumpString(output,
cur->stringval);
1453#ifdef LIBXML_XPTR_LOCS_ENABLED
1455 fprintf(output,
"Object is a point : index %d in node",
cur->index);
1461 ((
cur->user2 ==
cur->user) && (
cur->index ==
cur->index2))) {
1462 fprintf(output,
"Object is a collapsed range :\n");
1464 if (
cur->index >= 0)
1470 fprintf(output,
"Object is a range :\n");
1473 if (
cur->index >= 0)
1480 if (
cur->index2 >= 0)
1481 fprintf(output,
"index %d in ",
cur->index2);
1488 case XPATH_LOCATIONSET:
1489 fprintf(output,
"Object is a Location Set:\n");
1490 xmlXPathDebugDumpLocationSet(output,
1491 (xmlLocationSetPtr)
cur->user,
depth);
1495 fprintf(output,
"Object is user defined\n");
1501xmlXPathDebugDumpStepOp(
FILE *output, xmlXPathCompExprPtr comp,
1502 xmlXPathStepOpPtr
op,
int depth) {
1506 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1512 fprintf(output,
"Step is NULL\n");
1517 fprintf(output,
"END");
break;
1519 fprintf(output,
"AND");
break;
1522 case XPATH_OP_EQUAL:
1539 else if (
op->value == 1)
1541 else if (
op->value == 2)
1542 fprintf(output,
"PLUS unary -");
1543 else if (
op->value == 3)
1544 fprintf(output,
"PLUS unary - -");
1549 else if (
op->value == 1)
1554 case XPATH_OP_UNION:
1555 fprintf(output,
"UNION");
break;
1557 fprintf(output,
"ROOT");
break;
1559 fprintf(output,
"NODE");
break;
1561 fprintf(output,
"SORT");
break;
1562 case XPATH_OP_COLLECT: {
1563 xmlXPathAxisVal axis = (xmlXPathAxisVal)
op->value;
1564 xmlXPathTestVal
test = (xmlXPathTestVal)
op->value2;
1565 xmlXPathTypeVal
type = (xmlXPathTypeVal)
op->value3;
1572 fprintf(output,
" 'ancestors' ");
break;
1573 case AXIS_ANCESTOR_OR_SELF:
1574 fprintf(output,
" 'ancestors-or-self' ");
break;
1576 fprintf(output,
" 'attributes' ");
break;
1578 fprintf(output,
" 'child' ");
break;
1579 case AXIS_DESCENDANT:
1580 fprintf(output,
" 'descendant' ");
break;
1581 case AXIS_DESCENDANT_OR_SELF:
1582 fprintf(output,
" 'descendant-or-self' ");
break;
1583 case AXIS_FOLLOWING:
1584 fprintf(output,
" 'following' ");
break;
1585 case AXIS_FOLLOWING_SIBLING:
1586 fprintf(output,
" 'following-siblings' ");
break;
1587 case AXIS_NAMESPACE:
1588 fprintf(output,
" 'namespace' ");
break;
1590 fprintf(output,
" 'parent' ");
break;
1591 case AXIS_PRECEDING:
1592 fprintf(output,
" 'preceding' ");
break;
1593 case AXIS_PRECEDING_SIBLING:
1594 fprintf(output,
" 'preceding-sibling' ");
break;
1596 fprintf(output,
" 'self' ");
break;
1599 case NODE_TEST_NONE:
1600 fprintf(output,
"'none' ");
break;
1601 case NODE_TEST_TYPE:
1602 fprintf(output,
"'type' ");
break;
1604 fprintf(output,
"'PI' ");
break;
1606 fprintf(output,
"'all' ");
break;
1608 fprintf(output,
"'namespace' ");
break;
1609 case NODE_TEST_NAME:
1610 fprintf(output,
"'name' ");
break;
1613 case NODE_TYPE_NODE:
1614 fprintf(output,
"'node' ");
break;
1615 case NODE_TYPE_COMMENT:
1616 fprintf(output,
"'comment' ");
break;
1617 case NODE_TYPE_TEXT:
1618 fprintf(output,
"'text' ");
break;
1620 fprintf(output,
"'PI' ");
break;
1623 fprintf(output,
"%s:", prefix);
1629 case XPATH_OP_VALUE: {
1630 xmlXPathObjectPtr
object = (xmlXPathObjectPtr)
op->value4;
1633 xmlXPathDebugDumpObject(output,
object, 0);
1636 case XPATH_OP_VARIABLE: {
1646 case XPATH_OP_FUNCTION: {
1647 int nbargs =
op->value;
1652 fprintf(output,
"FUNCTION %s:%s(%d args)",
1653 prefix,
name, nbargs);
1655 fprintf(output,
"FUNCTION %s(%d args)",
name, nbargs);
1658 case XPATH_OP_ARG:
fprintf(output,
"ARG");
break;
1659 case XPATH_OP_PREDICATE:
fprintf(output,
"PREDICATE");
break;
1660 case XPATH_OP_FILTER:
fprintf(output,
"FILTER");
break;
1661#ifdef LIBXML_XPTR_LOCS_ENABLED
1662 case XPATH_OP_RANGETO:
fprintf(output,
"RANGETO");
break;
1665 fprintf(output,
"UNKNOWN %d\n",
op->op);
return;
1670 xmlXPathDebugDumpStepOp(output, comp, &comp->steps[
op->ch1],
depth + 1);
1672 xmlXPathDebugDumpStepOp(output, comp, &comp->steps[
op->ch2],
depth + 1);
1684xmlXPathDebugDumpCompExpr(
FILE *output, xmlXPathCompExprPtr comp,
1689 if ((output ==
NULL) || (comp ==
NULL))
return;
1691 for (
i = 0;((
i <
depth) && (
i < 25));
i++)
1697#ifdef XPATH_STREAMING
1699 fprintf(output,
"Streaming Expression\n");
1703 fprintf(output,
"Compiled Expression : %d elements\n",
1706 xmlXPathDebugDumpStepOp(output, comp, &comp->steps[
i],
depth + 1);
1710#ifdef XP_DEBUG_OBJ_USAGE
1715static int xmlXPathDebugObjCounterUndefined = 0;
1716static int xmlXPathDebugObjCounterNodeset = 0;
1717static int xmlXPathDebugObjCounterBool = 0;
1718static int xmlXPathDebugObjCounterNumber = 0;
1719static int xmlXPathDebugObjCounterString = 0;
1720static int xmlXPathDebugObjCounterPoint = 0;
1721static int xmlXPathDebugObjCounterRange = 0;
1722static int xmlXPathDebugObjCounterLocset = 0;
1723static int xmlXPathDebugObjCounterUsers = 0;
1724static int xmlXPathDebugObjCounterXSLTTree = 0;
1725static int xmlXPathDebugObjCounterAll = 0;
1727static int xmlXPathDebugObjTotalUndefined = 0;
1728static int xmlXPathDebugObjTotalNodeset = 0;
1729static int xmlXPathDebugObjTotalBool = 0;
1730static int xmlXPathDebugObjTotalNumber = 0;
1731static int xmlXPathDebugObjTotalString = 0;
1732static int xmlXPathDebugObjTotalPoint = 0;
1733static int xmlXPathDebugObjTotalRange = 0;
1734static int xmlXPathDebugObjTotalLocset = 0;
1735static int xmlXPathDebugObjTotalUsers = 0;
1736static int xmlXPathDebugObjTotalXSLTTree = 0;
1737static int xmlXPathDebugObjTotalAll = 0;
1739static int xmlXPathDebugObjMaxUndefined = 0;
1740static int xmlXPathDebugObjMaxNodeset = 0;
1741static int xmlXPathDebugObjMaxBool = 0;
1742static int xmlXPathDebugObjMaxNumber = 0;
1743static int xmlXPathDebugObjMaxString = 0;
1744static int xmlXPathDebugObjMaxPoint = 0;
1745static int xmlXPathDebugObjMaxRange = 0;
1746static int xmlXPathDebugObjMaxLocset = 0;
1747static int xmlXPathDebugObjMaxUsers = 0;
1748static int xmlXPathDebugObjMaxXSLTTree = 0;
1749static int xmlXPathDebugObjMaxAll = 0;
1752xmlXPathDebugObjUsageReset(xmlXPathContextPtr ctxt)
1755 if (ctxt->cache !=
NULL) {
1756 xmlXPathContextCachePtr
cache =
1757 (xmlXPathContextCachePtr) ctxt->cache;
1759 cache->dbgCachedAll = 0;
1760 cache->dbgCachedNodeset = 0;
1761 cache->dbgCachedString = 0;
1762 cache->dbgCachedBool = 0;
1763 cache->dbgCachedNumber = 0;
1764 cache->dbgCachedPoint = 0;
1765 cache->dbgCachedRange = 0;
1766 cache->dbgCachedLocset = 0;
1767 cache->dbgCachedUsers = 0;
1768 cache->dbgCachedXSLTTree = 0;
1769 cache->dbgCachedUndefined = 0;
1771 cache->dbgReusedAll = 0;
1772 cache->dbgReusedNodeset = 0;
1773 cache->dbgReusedString = 0;
1774 cache->dbgReusedBool = 0;
1775 cache->dbgReusedNumber = 0;
1776 cache->dbgReusedPoint = 0;
1777 cache->dbgReusedRange = 0;
1778 cache->dbgReusedLocset = 0;
1779 cache->dbgReusedUsers = 0;
1780 cache->dbgReusedXSLTTree = 0;
1781 cache->dbgReusedUndefined = 0;
1785 xmlXPathDebugObjCounterUndefined = 0;
1786 xmlXPathDebugObjCounterNodeset = 0;
1787 xmlXPathDebugObjCounterBool = 0;
1788 xmlXPathDebugObjCounterNumber = 0;
1789 xmlXPathDebugObjCounterString = 0;
1790 xmlXPathDebugObjCounterPoint = 0;
1791 xmlXPathDebugObjCounterRange = 0;
1792 xmlXPathDebugObjCounterLocset = 0;
1793 xmlXPathDebugObjCounterUsers = 0;
1794 xmlXPathDebugObjCounterXSLTTree = 0;
1795 xmlXPathDebugObjCounterAll = 0;
1797 xmlXPathDebugObjTotalUndefined = 0;
1798 xmlXPathDebugObjTotalNodeset = 0;
1799 xmlXPathDebugObjTotalBool = 0;
1800 xmlXPathDebugObjTotalNumber = 0;
1801 xmlXPathDebugObjTotalString = 0;
1802 xmlXPathDebugObjTotalPoint = 0;
1803 xmlXPathDebugObjTotalRange = 0;
1804 xmlXPathDebugObjTotalLocset = 0;
1805 xmlXPathDebugObjTotalUsers = 0;
1806 xmlXPathDebugObjTotalXSLTTree = 0;
1807 xmlXPathDebugObjTotalAll = 0;
1809 xmlXPathDebugObjMaxUndefined = 0;
1810 xmlXPathDebugObjMaxNodeset = 0;
1811 xmlXPathDebugObjMaxBool = 0;
1812 xmlXPathDebugObjMaxNumber = 0;
1813 xmlXPathDebugObjMaxString = 0;
1814 xmlXPathDebugObjMaxPoint = 0;
1815 xmlXPathDebugObjMaxRange = 0;
1816 xmlXPathDebugObjMaxLocset = 0;
1817 xmlXPathDebugObjMaxUsers = 0;
1818 xmlXPathDebugObjMaxXSLTTree = 0;
1819 xmlXPathDebugObjMaxAll = 0;
1824xmlXPathDebugObjUsageRequested(xmlXPathContextPtr ctxt,
1825 xmlXPathObjectType objType)
1830 if (ctxt->cache !=
NULL) {
1831 xmlXPathContextCachePtr
cache =
1832 (xmlXPathContextCachePtr) ctxt->cache;
1836 cache->dbgReusedAll++;
1838 case XPATH_UNDEFINED:
1839 cache->dbgReusedUndefined++;
1842 cache->dbgReusedNodeset++;
1845 cache->dbgReusedBool++;
1848 cache->dbgReusedNumber++;
1851 cache->dbgReusedString++;
1853#ifdef LIBXML_XPTR_LOCS_ENABLED
1855 cache->dbgReusedPoint++;
1858 cache->dbgReusedRange++;
1860 case XPATH_LOCATIONSET:
1861 cache->dbgReusedLocset++;
1865 cache->dbgReusedUsers++;
1867 case XPATH_XSLT_TREE:
1868 cache->dbgReusedXSLTTree++;
1877 case XPATH_UNDEFINED:
1879 xmlXPathDebugObjTotalUndefined++;
1880 xmlXPathDebugObjCounterUndefined++;
1881 if (xmlXPathDebugObjCounterUndefined >
1882 xmlXPathDebugObjMaxUndefined)
1883 xmlXPathDebugObjMaxUndefined =
1884 xmlXPathDebugObjCounterUndefined;
1888 xmlXPathDebugObjTotalNodeset++;
1889 xmlXPathDebugObjCounterNodeset++;
1890 if (xmlXPathDebugObjCounterNodeset >
1891 xmlXPathDebugObjMaxNodeset)
1892 xmlXPathDebugObjMaxNodeset =
1893 xmlXPathDebugObjCounterNodeset;
1897 xmlXPathDebugObjTotalBool++;
1898 xmlXPathDebugObjCounterBool++;
1899 if (xmlXPathDebugObjCounterBool >
1900 xmlXPathDebugObjMaxBool)
1901 xmlXPathDebugObjMaxBool =
1902 xmlXPathDebugObjCounterBool;
1906 xmlXPathDebugObjTotalNumber++;
1907 xmlXPathDebugObjCounterNumber++;
1908 if (xmlXPathDebugObjCounterNumber >
1909 xmlXPathDebugObjMaxNumber)
1910 xmlXPathDebugObjMaxNumber =
1911 xmlXPathDebugObjCounterNumber;
1915 xmlXPathDebugObjTotalString++;
1916 xmlXPathDebugObjCounterString++;
1917 if (xmlXPathDebugObjCounterString >
1918 xmlXPathDebugObjMaxString)
1919 xmlXPathDebugObjMaxString =
1920 xmlXPathDebugObjCounterString;
1922#ifdef LIBXML_XPTR_LOCS_ENABLED
1925 xmlXPathDebugObjTotalPoint++;
1926 xmlXPathDebugObjCounterPoint++;
1927 if (xmlXPathDebugObjCounterPoint >
1928 xmlXPathDebugObjMaxPoint)
1929 xmlXPathDebugObjMaxPoint =
1930 xmlXPathDebugObjCounterPoint;
1934 xmlXPathDebugObjTotalRange++;
1935 xmlXPathDebugObjCounterRange++;
1936 if (xmlXPathDebugObjCounterRange >
1937 xmlXPathDebugObjMaxRange)
1938 xmlXPathDebugObjMaxRange =
1939 xmlXPathDebugObjCounterRange;
1941 case XPATH_LOCATIONSET:
1943 xmlXPathDebugObjTotalLocset++;
1944 xmlXPathDebugObjCounterLocset++;
1945 if (xmlXPathDebugObjCounterLocset >
1946 xmlXPathDebugObjMaxLocset)
1947 xmlXPathDebugObjMaxLocset =
1948 xmlXPathDebugObjCounterLocset;
1953 xmlXPathDebugObjTotalUsers++;
1954 xmlXPathDebugObjCounterUsers++;
1955 if (xmlXPathDebugObjCounterUsers >
1956 xmlXPathDebugObjMaxUsers)
1957 xmlXPathDebugObjMaxUsers =
1958 xmlXPathDebugObjCounterUsers;
1960 case XPATH_XSLT_TREE:
1962 xmlXPathDebugObjTotalXSLTTree++;
1963 xmlXPathDebugObjCounterXSLTTree++;
1964 if (xmlXPathDebugObjCounterXSLTTree >
1965 xmlXPathDebugObjMaxXSLTTree)
1966 xmlXPathDebugObjMaxXSLTTree =
1967 xmlXPathDebugObjCounterXSLTTree;
1973 xmlXPathDebugObjTotalAll++;
1974 xmlXPathDebugObjCounterAll++;
1975 if (xmlXPathDebugObjCounterAll >
1976 xmlXPathDebugObjMaxAll)
1977 xmlXPathDebugObjMaxAll =
1978 xmlXPathDebugObjCounterAll;
1982xmlXPathDebugObjUsageReleased(xmlXPathContextPtr ctxt,
1983 xmlXPathObjectType objType)
1988 if (ctxt->cache !=
NULL) {
1989 xmlXPathContextCachePtr
cache =
1990 (xmlXPathContextCachePtr) ctxt->cache;
1994 cache->dbgCachedAll++;
1996 case XPATH_UNDEFINED:
1997 cache->dbgCachedUndefined++;
2000 cache->dbgCachedNodeset++;
2003 cache->dbgCachedBool++;
2006 cache->dbgCachedNumber++;
2009 cache->dbgCachedString++;
2011#ifdef LIBXML_XPTR_LOCS_ENABLED
2013 cache->dbgCachedPoint++;
2016 cache->dbgCachedRange++;
2018 case XPATH_LOCATIONSET:
2019 cache->dbgCachedLocset++;
2023 cache->dbgCachedUsers++;
2025 case XPATH_XSLT_TREE:
2026 cache->dbgCachedXSLTTree++;
2035 case XPATH_UNDEFINED:
2036 xmlXPathDebugObjCounterUndefined--;
2039 xmlXPathDebugObjCounterNodeset--;
2042 xmlXPathDebugObjCounterBool--;
2045 xmlXPathDebugObjCounterNumber--;
2048 xmlXPathDebugObjCounterString--;
2050#ifdef LIBXML_XPTR_LOCS_ENABLED
2052 xmlXPathDebugObjCounterPoint--;
2055 xmlXPathDebugObjCounterRange--;
2057 case XPATH_LOCATIONSET:
2058 xmlXPathDebugObjCounterLocset--;
2062 xmlXPathDebugObjCounterUsers--;
2064 case XPATH_XSLT_TREE:
2065 xmlXPathDebugObjCounterXSLTTree--;
2070 xmlXPathDebugObjCounterAll--;
2074xmlXPathDebugObjUsageDisplay(xmlXPathContextPtr ctxt)
2076 int reqAll, reqNodeset, reqString, reqBool, reqNumber,
2077 reqXSLTTree, reqUndefined;
2078 int caAll = 0, caNodeset = 0, caString = 0, caBool = 0,
2079 caNumber = 0, caXSLTTree = 0, caUndefined = 0;
2080 int reAll = 0, reNodeset = 0, reString = 0, reBool = 0,
2081 reNumber = 0, reXSLTTree = 0, reUndefined = 0;
2082 int leftObjs = xmlXPathDebugObjCounterAll;
2084 reqAll = xmlXPathDebugObjTotalAll;
2085 reqNodeset = xmlXPathDebugObjTotalNodeset;
2086 reqString = xmlXPathDebugObjTotalString;
2087 reqBool = xmlXPathDebugObjTotalBool;
2088 reqNumber = xmlXPathDebugObjTotalNumber;
2089 reqXSLTTree = xmlXPathDebugObjTotalXSLTTree;
2090 reqUndefined = xmlXPathDebugObjTotalUndefined;
2092 printf(
"# XPath object usage:\n");
2095 if (ctxt->cache !=
NULL) {
2096 xmlXPathContextCachePtr
cache =
2097 (xmlXPathContextCachePtr) ctxt->cache;
2099 reAll =
cache->dbgReusedAll;
2101 reNodeset =
cache->dbgReusedNodeset;
2102 reqNodeset += reNodeset;
2103 reString =
cache->dbgReusedString;
2104 reqString += reString;
2105 reBool =
cache->dbgReusedBool;
2107 reNumber =
cache->dbgReusedNumber;
2108 reqNumber += reNumber;
2109 reXSLTTree =
cache->dbgReusedXSLTTree;
2110 reqXSLTTree += reXSLTTree;
2111 reUndefined =
cache->dbgReusedUndefined;
2112 reqUndefined += reUndefined;
2114 caAll =
cache->dbgCachedAll;
2115 caBool =
cache->dbgCachedBool;
2116 caNodeset =
cache->dbgCachedNodeset;
2117 caString =
cache->dbgCachedString;
2118 caNumber =
cache->dbgCachedNumber;
2119 caXSLTTree =
cache->dbgCachedXSLTTree;
2120 caUndefined =
cache->dbgCachedUndefined;
2123 leftObjs -=
cache->nodesetObjs->number;
2124 if (
cache->stringObjs)
2125 leftObjs -=
cache->stringObjs->number;
2126 if (
cache->booleanObjs)
2127 leftObjs -=
cache->booleanObjs->number;
2128 if (
cache->numberObjs)
2129 leftObjs -=
cache->numberObjs->number;
2130 if (
cache->miscObjs)
2131 leftObjs -=
cache->miscObjs->number;
2136 printf(
"# total : %d\n", reqAll);
2137 printf(
"# left : %d\n", leftObjs);
2138 printf(
"# created: %d\n", xmlXPathDebugObjTotalAll);
2139 printf(
"# reused : %d\n", reAll);
2140 printf(
"# max : %d\n", xmlXPathDebugObjMaxAll);
2143 printf(
"# total : %d\n", reqNodeset);
2144 printf(
"# created: %d\n", xmlXPathDebugObjTotalNodeset);
2145 printf(
"# reused : %d\n", reNodeset);
2146 printf(
"# max : %d\n", xmlXPathDebugObjMaxNodeset);
2149 printf(
"# total : %d\n", reqString);
2150 printf(
"# created: %d\n", xmlXPathDebugObjTotalString);
2151 printf(
"# reused : %d\n", reString);
2152 printf(
"# max : %d\n", xmlXPathDebugObjMaxString);
2155 printf(
"# total : %d\n", reqBool);
2156 printf(
"# created: %d\n", xmlXPathDebugObjTotalBool);
2157 printf(
"# reused : %d\n", reBool);
2158 printf(
"# max : %d\n", xmlXPathDebugObjMaxBool);
2161 printf(
"# total : %d\n", reqNumber);
2162 printf(
"# created: %d\n", xmlXPathDebugObjTotalNumber);
2163 printf(
"# reused : %d\n", reNumber);
2164 printf(
"# max : %d\n", xmlXPathDebugObjMaxNumber);
2166 printf(
"# XSLT result tree fragments\n");
2167 printf(
"# total : %d\n", reqXSLTTree);
2168 printf(
"# created: %d\n", xmlXPathDebugObjTotalXSLTTree);
2169 printf(
"# reused : %d\n", reXSLTTree);
2170 printf(
"# max : %d\n", xmlXPathDebugObjMaxXSLTTree);
2173 printf(
"# total : %d\n", reqUndefined);
2174 printf(
"# created: %d\n", xmlXPathDebugObjTotalUndefined);
2175 printf(
"# reused : %d\n", reUndefined);
2176 printf(
"# max : %d\n", xmlXPathDebugObjMaxUndefined);
2197static xmlXPathContextCachePtr
2198xmlXPathNewCache(
void)
2200 xmlXPathContextCachePtr
ret;
2202 ret = (xmlXPathContextCachePtr)
xmlMalloc(
sizeof(xmlXPathContextCache));
2204 xmlXPathErrMemory(
NULL,
"creating object cache\n");
2207 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathContextCache));
2208 ret->maxNodeset = 100;
2209 ret->maxString = 100;
2210 ret->maxBoolean = 100;
2211 ret->maxNumber = 100;
2217xmlXPathCacheFreeObjectList(xmlPointerListPtr
list)
2220 xmlXPathObjectPtr
obj;
2225 for (
i = 0;
i <
list->number;
i++) {
2231 if (
obj->nodesetval !=
NULL) {
2232 if (
obj->nodesetval->nodeTab !=
NULL)
2237#ifdef XP_DEBUG_OBJ_USAGE
2238 xmlXPathDebugObjCounterAll--;
2241 xmlPointerListFree(
list);
2245xmlXPathFreeCache(xmlXPathContextCachePtr
cache)
2249 if (
cache->nodesetObjs)
2250 xmlXPathCacheFreeObjectList(
cache->nodesetObjs);
2251 if (
cache->stringObjs)
2252 xmlXPathCacheFreeObjectList(
cache->stringObjs);
2253 if (
cache->booleanObjs)
2254 xmlXPathCacheFreeObjectList(
cache->booleanObjs);
2255 if (
cache->numberObjs)
2256 xmlXPathCacheFreeObjectList(
cache->numberObjs);
2257 if (
cache->miscObjs)
2258 xmlXPathCacheFreeObjectList(
cache->miscObjs);
2285xmlXPathContextSetCache(xmlXPathContextPtr ctxt,
2293 xmlXPathContextCachePtr
cache;
2295 if (ctxt->cache ==
NULL) {
2296 ctxt->cache = xmlXPathNewCache();
2297 if (ctxt->cache ==
NULL)
2300 cache = (xmlXPathContextCachePtr) ctxt->cache;
2310 }
else if (ctxt->cache !=
NULL) {
2311 xmlXPathFreeCache((xmlXPathContextCachePtr) ctxt->cache);
2327static xmlXPathObjectPtr
2328xmlXPathCacheWrapNodeSet(xmlXPathContextPtr ctxt, xmlNodeSetPtr
val)
2330 if ((ctxt !=
NULL) && (ctxt->cache !=
NULL)) {
2331 xmlXPathContextCachePtr
cache =
2332 (xmlXPathContextCachePtr) ctxt->cache;
2335 (
cache->miscObjs->number != 0))
2337 xmlXPathObjectPtr
ret;
2339 ret = (xmlXPathObjectPtr)
2340 cache->miscObjs->items[--
cache->miscObjs->number];
2341 ret->type = XPATH_NODESET;
2343#ifdef XP_DEBUG_OBJ_USAGE
2344 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2350 return(xmlXPathWrapNodeSet(
val));
2364static xmlXPathObjectPtr
2365xmlXPathCacheWrapString(xmlXPathContextPtr ctxt,
xmlChar *
val)
2367 if ((ctxt !=
NULL) && (ctxt->cache !=
NULL)) {
2368 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2371 (
cache->stringObjs->number != 0))
2374 xmlXPathObjectPtr
ret;
2376 ret = (xmlXPathObjectPtr)
2377 cache->stringObjs->items[--
cache->stringObjs->number];
2378 ret->type = XPATH_STRING;
2380#ifdef XP_DEBUG_OBJ_USAGE
2381 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2385 (
cache->miscObjs->number != 0))
2387 xmlXPathObjectPtr
ret;
2391 ret = (xmlXPathObjectPtr)
2392 cache->miscObjs->items[--
cache->miscObjs->number];
2394 ret->type = XPATH_STRING;
2396#ifdef XP_DEBUG_OBJ_USAGE
2397 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2402 return(xmlXPathWrapString(
val));
2416static xmlXPathObjectPtr
2417xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt,
xmlNodePtr val)
2419 if ((ctxt !=
NULL) && (ctxt->cache)) {
2420 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2423 (
cache->nodesetObjs->number != 0))
2425 xmlXPathObjectPtr
ret;
2429 ret = (xmlXPathObjectPtr)
2430 cache->nodesetObjs->items[--
cache->nodesetObjs->number];
2431 ret->type = XPATH_NODESET;
2434 if ((
ret->nodesetval->nodeMax == 0) ||
2438 xmlXPathNodeSetAddUnique(
ret->nodesetval,
val);
2440 ret->nodesetval->nodeTab[0] =
val;
2441 ret->nodesetval->nodeNr = 1;
2444#ifdef XP_DEBUG_OBJ_USAGE
2445 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2449 (
cache->miscObjs->number != 0))
2451 xmlXPathObjectPtr
ret;
2456 ret = (xmlXPathObjectPtr)
2457 cache->miscObjs->items[--
cache->miscObjs->number];
2459 ret->type = XPATH_NODESET;
2461 ret->nodesetval = xmlXPathNodeSetCreate(
val);
2462 if (
ret->nodesetval ==
NULL) {
2467#ifdef XP_DEBUG_OBJ_USAGE
2468 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NODESET);
2473 return(xmlXPathNewNodeSet(
val));
2486static xmlXPathObjectPtr
2487xmlXPathCacheNewCString(xmlXPathContextPtr ctxt,
const char *
val)
2489 if ((ctxt !=
NULL) && (ctxt->cache)) {
2490 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2493 (
cache->stringObjs->number != 0))
2495 xmlXPathObjectPtr
ret;
2497 ret = (xmlXPathObjectPtr)
2498 cache->stringObjs->items[--
cache->stringObjs->number];
2500 ret->type = XPATH_STRING;
2502#ifdef XP_DEBUG_OBJ_USAGE
2503 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2507 (
cache->miscObjs->number != 0))
2509 xmlXPathObjectPtr
ret;
2511 ret = (xmlXPathObjectPtr)
2512 cache->miscObjs->items[--
cache->miscObjs->number];
2514 ret->type = XPATH_STRING;
2516#ifdef XP_DEBUG_OBJ_USAGE
2517 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2522 return(xmlXPathNewCString(
val));
2535static xmlXPathObjectPtr
2536xmlXPathCacheNewString(xmlXPathContextPtr ctxt,
const xmlChar *
val)
2538 if ((ctxt !=
NULL) && (ctxt->cache)) {
2539 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2542 (
cache->stringObjs->number != 0))
2544 xmlXPathObjectPtr
ret;
2546 ret = (xmlXPathObjectPtr)
2547 cache->stringObjs->items[--
cache->stringObjs->number];
2548 ret->type = XPATH_STRING;
2553#ifdef XP_DEBUG_OBJ_USAGE
2554 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2558 (
cache->miscObjs->number != 0))
2560 xmlXPathObjectPtr
ret;
2562 ret = (xmlXPathObjectPtr)
2563 cache->miscObjs->items[--
cache->miscObjs->number];
2565 ret->type = XPATH_STRING;
2570#ifdef XP_DEBUG_OBJ_USAGE
2571 xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
2576 return(xmlXPathNewString(
val));
2589static xmlXPathObjectPtr
2590xmlXPathCacheNewBoolean(xmlXPathContextPtr ctxt,
int val)
2592 if ((ctxt !=
NULL) && (ctxt->cache)) {
2593 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2596 (
cache->booleanObjs->number != 0))
2598 xmlXPathObjectPtr
ret;
2600 ret = (xmlXPathObjectPtr)
2601 cache->booleanObjs->items[--
cache->booleanObjs->number];
2602 ret->type = XPATH_BOOLEAN;
2603 ret->boolval = (
val != 0);
2604#ifdef XP_DEBUG_OBJ_USAGE
2605 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2609 (
cache->miscObjs->number != 0))
2611 xmlXPathObjectPtr
ret;
2613 ret = (xmlXPathObjectPtr)
2614 cache->miscObjs->items[--
cache->miscObjs->number];
2616 ret->type = XPATH_BOOLEAN;
2617 ret->boolval = (
val != 0);
2618#ifdef XP_DEBUG_OBJ_USAGE
2619 xmlXPathDebugObjUsageRequested(ctxt, XPATH_BOOLEAN);
2624 return(xmlXPathNewBoolean(
val));
2637static xmlXPathObjectPtr
2638xmlXPathCacheNewFloat(xmlXPathContextPtr ctxt,
double val)
2640 if ((ctxt !=
NULL) && (ctxt->cache)) {
2641 xmlXPathContextCachePtr
cache = (xmlXPathContextCachePtr) ctxt->cache;
2644 (
cache->numberObjs->number != 0))
2646 xmlXPathObjectPtr
ret;
2648 ret = (xmlXPathObjectPtr)
2649 cache->numberObjs->items[--
cache->numberObjs->number];
2650 ret->type = XPATH_NUMBER;
2652#ifdef XP_DEBUG_OBJ_USAGE
2653 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2657 (
cache->miscObjs->number != 0))
2659 xmlXPathObjectPtr
ret;
2661 ret = (xmlXPathObjectPtr)
2662 cache->miscObjs->items[--
cache->miscObjs->number];
2664 ret->type = XPATH_NUMBER;
2666#ifdef XP_DEBUG_OBJ_USAGE
2667 xmlXPathDebugObjUsageRequested(ctxt, XPATH_NUMBER);
2672 return(xmlXPathNewFloat(
val));
2687static xmlXPathObjectPtr
2688xmlXPathCacheConvertString(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2692 return(xmlXPathCacheNewCString(ctxt,
""));
2694 switch (
val->type) {
2695 case XPATH_UNDEFINED:
2701 case XPATH_XSLT_TREE:
2702 res = xmlXPathCastNodeSetToString(
val->nodesetval);
2707 res = xmlXPathCastBooleanToString(
val->boolval);
2710 res = xmlXPathCastNumberToString(
val->floatval);
2713#ifdef LIBXML_XPTR_LOCS_ENABLED
2716 case XPATH_LOCATIONSET:
2721 xmlXPathReleaseObject(ctxt,
val);
2723 return(xmlXPathCacheNewCString(ctxt,
""));
2724 return(xmlXPathCacheWrapString(ctxt,
res));
2737static xmlXPathObjectPtr
2738xmlXPathCacheObjectCopy(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val)
2743 if (XP_HAS_CACHE(ctxt)) {
2744 switch (
val->type) {
2746 return(xmlXPathCacheWrapNodeSet(ctxt,
2747 xmlXPathNodeSetMerge(
NULL,
val->nodesetval)));
2749 return(xmlXPathCacheNewString(ctxt,
val->stringval));
2751 return(xmlXPathCacheNewBoolean(ctxt,
val->boolval));
2753 return(xmlXPathCacheNewFloat(ctxt,
val->floatval));
2758 return(xmlXPathObjectCopy(
val));
2772static xmlXPathObjectPtr
2773xmlXPathCacheConvertBoolean(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2774 xmlXPathObjectPtr
ret;
2777 return(xmlXPathCacheNewBoolean(ctxt, 0));
2778 if (
val->type == XPATH_BOOLEAN)
2780 ret = xmlXPathCacheNewBoolean(ctxt, xmlXPathCastToBoolean(
val));
2781 xmlXPathReleaseObject(ctxt,
val);
2796static xmlXPathObjectPtr
2797xmlXPathCacheConvertNumber(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
val) {
2798 xmlXPathObjectPtr
ret;
2801 return(xmlXPathCacheNewFloat(ctxt, 0.0));
2802 if (
val->type == XPATH_NUMBER)
2804 ret = xmlXPathCacheNewFloat(ctxt, xmlXPathCastToNumber(
val));
2805 xmlXPathReleaseObject(ctxt,
val);
2824xmlXPathSetFrame(xmlXPathParserContextPtr ctxt) {
2829 ret = ctxt->valueFrame;
2830 ctxt->valueFrame = ctxt->valueNr;
2842xmlXPathPopFrame(xmlXPathParserContextPtr ctxt,
int frame) {
2845 if (ctxt->valueNr < ctxt->valueFrame) {
2846 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2848 ctxt->valueFrame = frame;
2860valuePop(xmlXPathParserContextPtr ctxt)
2862 xmlXPathObjectPtr
ret;
2864 if ((ctxt ==
NULL) || (ctxt->valueNr <= 0))
2867 if (ctxt->valueNr <= ctxt->valueFrame) {
2868 xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_STACK_ERROR);
2873 if (ctxt->valueNr > 0)
2874 ctxt->value = ctxt->valueTab[ctxt->valueNr - 1];
2877 ret = ctxt->valueTab[ctxt->valueNr];
2878 ctxt->valueTab[ctxt->valueNr] =
NULL;
2892valuePush(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr
value)
2894 if (ctxt ==
NULL)
return(-1);
2900 ctxt->error = XPATH_MEMORY_ERROR;
2903 if (ctxt->valueNr >= ctxt->valueMax) {
2904 xmlXPathObjectPtr *tmp;
2907 xmlXPathPErrMemory(ctxt,
"XPath stack depth limit reached\n");
2910 tmp = (xmlXPathObjectPtr *)
xmlRealloc(ctxt->valueTab,
2911 2 * ctxt->valueMax *
2912 sizeof(ctxt->valueTab[0]));
2914 xmlXPathPErrMemory(ctxt,
"pushing value\n");
2917 ctxt->valueMax *= 2;
2918 ctxt->valueTab = tmp;
2920 ctxt->valueTab[ctxt->valueNr] =
value;
2921 ctxt->value =
value;
2922 return (ctxt->valueNr++);
2935xmlXPathPopBoolean (xmlXPathParserContextPtr ctxt) {
2936 xmlXPathObjectPtr
obj;
2939 obj = valuePop(ctxt);
2941 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2944 if (
obj->type != XPATH_BOOLEAN)
2945 ret = xmlXPathCastToBoolean(
obj);
2948 xmlXPathReleaseObject(ctxt->context,
obj);
2962xmlXPathPopNumber (xmlXPathParserContextPtr ctxt) {
2963 xmlXPathObjectPtr
obj;
2966 obj = valuePop(ctxt);
2968 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2971 if (
obj->type != XPATH_NUMBER)
2972 ret = xmlXPathCastToNumber(
obj);
2975 xmlXPathReleaseObject(ctxt->context,
obj);
2989xmlXPathPopString (xmlXPathParserContextPtr ctxt) {
2990 xmlXPathObjectPtr
obj;
2993 obj = valuePop(ctxt);
2995 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
2998 ret = xmlXPathCastToString(
obj);
3000 if (
obj->stringval ==
ret)
3002 xmlXPathReleaseObject(ctxt->context,
obj);
3016xmlXPathPopNodeSet (xmlXPathParserContextPtr ctxt) {
3017 xmlXPathObjectPtr
obj;
3021 if (ctxt->value ==
NULL) {
3022 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
3025 if (!xmlXPathStackIsNodeSet(ctxt)) {
3026 xmlXPathSetTypeError(ctxt);
3029 obj = valuePop(ctxt);
3037 xmlXPathReleaseObject(ctxt->context,
obj);
3051xmlXPathPopExternal (xmlXPathParserContextPtr ctxt) {
3052 xmlXPathObjectPtr
obj;
3055 if ((ctxt ==
NULL) || (ctxt->value ==
NULL)) {
3056 xmlXPathSetError(ctxt, XPATH_INVALID_OPERAND);
3059 if (ctxt->value->type != XPATH_USERS) {
3060 xmlXPathSetTypeError(ctxt);
3063 obj = valuePop(ctxt);
3066 xmlXPathReleaseObject(ctxt->context,
obj);
3093#define CUR (*ctxt->cur)
3094#define SKIP(val) ctxt->cur += (val)
3095#define NXT(val) ctxt->cur[(val)]
3096#define CUR_PTR ctxt->cur
3097#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
3099#define COPY_BUF(l,b,i,v) \
3100 if (l == 1) b[i++] = (xmlChar) v; \
3101 else i += xmlCopyChar(l,&b[i],v)
3103#define NEXTL(l) ctxt->cur += l
3105#define SKIP_BLANKS \
3106 while (IS_BLANK_CH(*(ctxt->cur))) NEXT
3108#define CURRENT (*ctxt->cur)
3109#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
3116#define DBL_EPSILON 1E-9
3119#define UPPER_DOUBLE 1E9
3120#define LOWER_DOUBLE 1E-5
3121#define LOWER_DOUBLE_EXP 5
3123#define INTEGER_DIGITS DBL_DIG
3124#define FRACTION_DIGITS (DBL_DIG + 1 + (LOWER_DOUBLE_EXP))
3125#define EXPONENT_DIGITS (3 + 2)
3136xmlXPathFormatNumber(
double number,
char buffer[],
int buffersize)
3138 switch (xmlXPathIsInf(
number)) {
3140 if (buffersize > (
int)
sizeof(
"Infinity"))
3144 if (buffersize > (
int)
sizeof(
"-Infinity"))
3148 if (xmlXPathIsNaN(
number)) {
3149 if (buffersize > (
int)
sizeof(
"NaN"))
3151 }
else if (
number == 0) {
3172 }
else if (buffersize > 0) {
3186 char work[
DBL_DIG + EXPONENT_DIGITS + 3 + LOWER_DOUBLE_EXP];
3187 int integer_place, fraction_place;
3189 char *after_fraction;
3190 double absolute_value;
3200 if ( ((absolute_value > UPPER_DOUBLE) ||
3201 (absolute_value < LOWER_DOUBLE)) &&
3202 (absolute_value != 0.0) ) {
3204 integer_place =
DBL_DIG + EXPONENT_DIGITS + 1;
3207 integer_place, fraction_place,
number);
3213 if (absolute_value > 0.0) {
3214 integer_place = (
int)
log10(absolute_value);
3215 if (integer_place > 0)
3216 fraction_place =
DBL_DIG - integer_place - 1;
3218 fraction_place =
DBL_DIG - integer_place;
3227 while (work[0] ==
' ') {
3233 after_fraction = work +
size;
3234 ptr = after_fraction;
3235 while (*(--
ptr) ==
'0')
3239 while ((*
ptr++ = *after_fraction++) != 0);
3243 if (
size > buffersize) {
3244 work[buffersize - 1] = 0;
3283 cur->content = (
void *) (-(++
count));
3307 return((
long)
count);
3323 int attr1 = 0, attr2 = 0;
3327 if ((node1 ==
NULL) || (node2 ==
NULL))
3344 if (node1 == node2) {
3345 if (attr1 == attr2) {
3348 cur = attrNode2->prev;
3350 if (
cur == attrNode1)
3365 if (node1 == node2->
prev)
3367 if (node1 == node2->
next)
3377 (node1->
doc == node2->
doc)) {
3392 if (
cur->parent == node1)
3398 if (
cur->parent == node2)
3411 while (depth1 > depth2) {
3415 while (depth2 > depth1) {
3423 if ((node1 ==
NULL) || (node2 ==
NULL))
3429 if (node1 == node2->
prev)
3431 if (node1 == node2->
next)
3440 (node1->
doc == node2->
doc)) {
3464xmlXPathNodeSetSort(xmlNodeSetPtr
set) {
3465#ifndef WITH_TIM_SORT
3466 int i,
j, incr,
len;
3473#ifndef WITH_TIM_SORT
3479 for (incr =
len / 2; incr > 0; incr /= 2) {
3480 for (
i = incr;
i <
len;
i++) {
3483#ifdef XP_OPTIMIZED_NON_ELEM_COMPARISON
3485 set->nodeTab[
j + incr]) == -1)
3487 if (xmlXPathCmpNodes(
set->nodeTab[
j],
3488 set->nodeTab[
j + incr]) == -1)
3491 tmp =
set->nodeTab[
j];
3492 set->nodeTab[
j] =
set->nodeTab[
j + incr];
3493 set->nodeTab[
j + incr] = tmp;
3501 libxml_domnode_tim_sort(
set->nodeTab,
set->nodeNr);
3505#define XML_NODESET_DEFAULT 10
3531 xmlXPathErrMemory(
NULL,
"duplicating namespace\n");
3580 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
3583 memset(
ret, 0 , (
size_t)
sizeof(xmlNodeSet));
3588 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
3593 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3594 ret->nodeMax = XML_NODESET_DEFAULT;
3599 ret->nodeTab[
ret->nodeNr++] =
3622 for (
i = 0;
i <
cur->nodeNr;
i++) {
3636 for (
i = 0;
i <
cur->nodeNr;
i++) {
3668 for (
i = 0;
i <
cur->nodeNr;
i++) {
3679 if (
cur->nodeMax == 0) {
3683 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3687 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3688 cur->nodeMax = XML_NODESET_DEFAULT;
3689 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3693 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3699 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3706 cur->nodeTab[
cur->nodeNr++] = xmlXPathNodeSetDupNs(
node,
ns);
3729 for (
i = 0;
i <
cur->nodeNr;
i++)
3730 if (
cur->nodeTab[
i] ==
val)
return(0);
3735 if (
cur->nodeMax == 0) {
3739 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3743 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3744 cur->nodeMax = XML_NODESET_DEFAULT;
3745 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3749 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3755 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3765 cur->nodeTab[
cur->nodeNr++] =
3790 if (
cur->nodeMax == 0) {
3794 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3798 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3799 cur->nodeMax = XML_NODESET_DEFAULT;
3800 }
else if (
cur->nodeNr ==
cur->nodeMax) {
3804 xmlXPathErrMemory(
NULL,
"growing nodeset hit limit\n");
3810 xmlXPathErrMemory(
NULL,
"growing nodeset\n");
3820 cur->nodeTab[
cur->nodeNr++] =
3838xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
3842 if (val2 ==
NULL)
return(val1);
3844 val1 = xmlXPathNodeSetCreate(
NULL);
3860 val1 = xmlXPathNodeSetCreateSize(val2->nodeNr);
3863 if (val2->nodeNr != 0) {
3864 if (val2->nodeNr == 1)
3865 *(val1->nodeTab) = *(val2->nodeTab);
3867 memcpy(val1->nodeTab, val2->nodeTab,
3870 val1->nodeNr = val2->nodeNr;
3877 initNr = val1->nodeNr;
3879 for (
i = 0;
i < val2->nodeNr;
i++) {
3880 n2 = val2->nodeTab[
i];
3885 for (
j = 0;
j < initNr;
j++) {
3886 n1 = val1->nodeTab[
j];
3907 if (val1->nodeMax == 0) {
3910 if (val1->nodeTab ==
NULL) {
3911 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
3914 memset(val1->nodeTab, 0 ,
3915 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
3916 val1->nodeMax = XML_NODESET_DEFAULT;
3917 }
else if (val1->nodeNr == val1->nodeMax) {
3921 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
3927 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
3930 val1->nodeTab =
temp;
3937 val1->nodeTab[val1->nodeNr++] =
3940 val1->nodeTab[val1->nodeNr++] =
n2;
3958xmlXPathNodeSetMergeAndClear(xmlNodeSetPtr
set1, xmlNodeSetPtr set2)
3961 int i,
j, initNbSet1;
3964 initNbSet1 =
set1->nodeNr;
3965 for (
i = 0;
i < set2->nodeNr;
i++) {
3966 n2 = set2->nodeTab[
i];
3970 for (
j = 0;
j < initNbSet1;
j++) {
3984 set2->nodeTab[
i] =
NULL;
3993 if (
set1->nodeMax == 0) {
3997 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4001 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
4002 set1->nodeMax = XML_NODESET_DEFAULT;
4003 }
else if (
set1->nodeNr >=
set1->nodeMax) {
4007 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
4013 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4039xmlXPathNodeSetMergeAndClearNoDupls(xmlNodeSetPtr
set1, xmlNodeSetPtr set2)
4045 for (
i = 0;
i < set2->nodeNr;
i++) {
4046 n2 = set2->nodeTab[
i];
4047 if (
set1->nodeMax == 0) {
4051 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4055 XML_NODESET_DEFAULT * (
size_t)
sizeof(
xmlNodePtr));
4056 set1->nodeMax = XML_NODESET_DEFAULT;
4057 }
else if (
set1->nodeNr >=
set1->nodeMax) {
4061 xmlXPathErrMemory(
NULL,
"merging nodeset hit limit\n");
4067 xmlXPathErrMemory(
NULL,
"merging nodeset\n");
4097 for (
i = 0;
i <
cur->nodeNr;
i++)
4098 if (
cur->nodeTab[
i] ==
val)
break;
4100 if (
i >=
cur->nodeNr) {
4103 "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
4112 for (;
i <
cur->nodeNr;
i++)
4113 cur->nodeTab[
i] =
cur->nodeTab[
i + 1];
4125xmlXPathNodeSetRemove(xmlNodeSetPtr
cur,
int val) {
4127 if (
val >=
cur->nodeNr)
return;
4144xmlXPathFreeNodeSet(xmlNodeSetPtr
obj) {
4150 for (
i = 0;
i <
obj->nodeNr;
i++)
4169xmlXPathNodeSetClearFromPos(xmlNodeSetPtr
set,
int pos,
int hasNsNodes)
4173 else if ((hasNsNodes)) {
4196xmlXPathNodeSetClear(xmlNodeSetPtr
set,
int hasNsNodes)
4198 xmlXPathNodeSetClearFromPos(
set, 0, hasNsNodes);
4210xmlXPathNodeSetKeepLast(xmlNodeSetPtr
set)
4217 for (
i = 0;
i <
set->nodeNr - 1;
i++) {
4223 set->nodeTab[0] =
set->nodeTab[
set->nodeNr-1];
4235xmlXPathFreeValueTree(xmlNodeSetPtr
obj) {
4241 for (
i = 0;
i <
obj->nodeNr;
i++) {
4255#if defined(DEBUG) || defined(DEBUG_STEP)
4264xmlGenericErrorContextNodeSet(
FILE *output, xmlNodeSetPtr
obj) {
4269 fprintf(output,
"NodeSet == NULL !\n");
4272 if (
obj->nodeNr == 0) {
4273 fprintf(output,
"NodeSet is empty\n");
4277 fprintf(output,
" nodeTab == NULL !\n");
4280 for (
i = 0;
i <
obj->nodeNr;
i++) {
4288 else if (
obj->nodeTab[
i]->name ==
NULL)
4290 else fprintf(output,
" %s",
obj->nodeTab[
i]->name);
4307 xmlXPathObjectPtr
ret;
4309 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4311 xmlXPathErrMemory(
NULL,
"creating nodeset\n");
4314 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4315 ret->type = XPATH_NODESET;
4318 ret->nodesetval = xmlXPathNodeSetCreate(
val);
4320#ifdef XP_DEBUG_OBJ_USAGE
4321 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NODESET);
4337 xmlXPathObjectPtr
ret;
4339 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4341 xmlXPathErrMemory(
NULL,
"creating result value tree\n");
4344 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4345 ret->type = XPATH_XSLT_TREE;
4347 ret->user = (
void *)
val;
4348 ret->nodesetval = xmlXPathNodeSetCreate(
val);
4349#ifdef XP_DEBUG_OBJ_USAGE
4350 xmlXPathDebugObjUsageRequested(
NULL, XPATH_XSLT_TREE);
4365xmlXPathNewNodeSetList(xmlNodeSetPtr
val)
4367 xmlXPathObjectPtr
ret;
4372 else if (
val->nodeTab ==
NULL)
4373 ret = xmlXPathNewNodeSet(
NULL);
4375 ret = xmlXPathNewNodeSet(
val->nodeTab[0]);
4377 for (
i = 1;
i <
val->nodeNr; ++
i) {
4379 if (xmlXPathNodeSetAddUnique(
ret->nodesetval,
val->nodeTab[
i])
4397xmlXPathWrapNodeSet(xmlNodeSetPtr
val) {
4398 xmlXPathObjectPtr
ret;
4400 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
4402 xmlXPathErrMemory(
NULL,
"creating node set object\n");
4405 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
4406 ret->type = XPATH_NODESET;
4408#ifdef XP_DEBUG_OBJ_USAGE
4409 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NODESET);
4422xmlXPathFreeNodeSetList(xmlXPathObjectPtr
obj) {
4424#ifdef XP_DEBUG_OBJ_USAGE
4425 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
4442xmlXPathDifference (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4447 if (xmlXPathNodeSetIsEmpty(nodes2))
4451 ret = xmlXPathNodeSetCreate(
NULL);
4452 if (xmlXPathNodeSetIsEmpty(nodes1))
4455 l1 = xmlXPathNodeSetGetLength(nodes1);
4457 for (
i = 0;
i < l1;
i++) {
4458 cur = xmlXPathNodeSetItem(nodes1,
i);
4459 if (!xmlXPathNodeSetContains(nodes2,
cur)) {
4461 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4480xmlXPathIntersection (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4481 xmlNodeSetPtr
ret = xmlXPathNodeSetCreate(
NULL);
4487 if (xmlXPathNodeSetIsEmpty(nodes1))
4489 if (xmlXPathNodeSetIsEmpty(nodes2))
4492 l1 = xmlXPathNodeSetGetLength(nodes1);
4494 for (
i = 0;
i < l1;
i++) {
4495 cur = xmlXPathNodeSetItem(nodes1,
i);
4496 if (xmlXPathNodeSetContains(nodes2,
cur)) {
4498 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4516xmlXPathDistinctSorted (xmlNodeSetPtr nodes) {
4523 if (xmlXPathNodeSetIsEmpty(nodes))
4526 ret = xmlXPathNodeSetCreate(
NULL);
4529 l = xmlXPathNodeSetGetLength(nodes);
4531 for (
i = 0;
i <
l;
i++) {
4532 cur = xmlXPathNodeSetItem(nodes,
i);
4537 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4560xmlXPathDistinct (xmlNodeSetPtr nodes) {
4561 if (xmlXPathNodeSetIsEmpty(nodes))
4564 xmlXPathNodeSetSort(nodes);
4565 return(xmlXPathDistinctSorted(nodes));
4580xmlXPathHasSameNodes (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4584 if (xmlXPathNodeSetIsEmpty(nodes1) ||
4585 xmlXPathNodeSetIsEmpty(nodes2))
4588 l = xmlXPathNodeSetGetLength(nodes1);
4589 for (
i = 0;
i <
l;
i++) {
4590 cur = xmlXPathNodeSetItem(nodes1,
i);
4591 if (xmlXPathNodeSetContains(nodes2,
cur))
4610xmlXPathNodeLeadingSorted (xmlNodeSetPtr nodes,
xmlNodePtr node) {
4618 ret = xmlXPathNodeSetCreate(
NULL);
4621 if (xmlXPathNodeSetIsEmpty(nodes) ||
4622 (!xmlXPathNodeSetContains(nodes,
node)))
4625 l = xmlXPathNodeSetGetLength(nodes);
4626 for (
i = 0;
i <
l;
i++) {
4627 cur = xmlXPathNodeSetItem(nodes,
i);
4631 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4653 xmlXPathNodeSetSort(nodes);
4654 return(xmlXPathNodeLeadingSorted(nodes,
node));
4670xmlXPathLeadingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4671 if (xmlXPathNodeSetIsEmpty(nodes2))
4673 return(xmlXPathNodeLeadingSorted(nodes1,
4674 xmlXPathNodeSetItem(nodes2, 1)));
4692xmlXPathLeading (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4693 if (xmlXPathNodeSetIsEmpty(nodes2))
4695 if (xmlXPathNodeSetIsEmpty(nodes1))
4696 return(xmlXPathNodeSetCreate(
NULL));
4697 xmlXPathNodeSetSort(nodes1);
4698 xmlXPathNodeSetSort(nodes2);
4699 return(xmlXPathNodeLeadingSorted(nodes1,
4700 xmlXPathNodeSetItem(nodes2, 1)));
4716xmlXPathNodeTrailingSorted (xmlNodeSetPtr nodes,
xmlNodePtr node) {
4724 ret = xmlXPathNodeSetCreate(
NULL);
4727 if (xmlXPathNodeSetIsEmpty(nodes) ||
4728 (!xmlXPathNodeSetContains(nodes,
node)))
4731 l = xmlXPathNodeSetGetLength(nodes);
4732 for (
i =
l - 1;
i >= 0;
i--) {
4733 cur = xmlXPathNodeSetItem(nodes,
i);
4737 if (xmlXPathNodeSetAddUnique(
ret,
cur) < 0)
4740 xmlXPathNodeSetSort(
ret);
4760 xmlXPathNodeSetSort(nodes);
4761 return(xmlXPathNodeTrailingSorted(nodes,
node));
4777xmlXPathTrailingSorted (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4778 if (xmlXPathNodeSetIsEmpty(nodes2))
4780 return(xmlXPathNodeTrailingSorted(nodes1,
4781 xmlXPathNodeSetItem(nodes2, 0)));
4799xmlXPathTrailing (xmlNodeSetPtr nodes1, xmlNodeSetPtr nodes2) {
4800 if (xmlXPathNodeSetIsEmpty(nodes2))
4802 if (xmlXPathNodeSetIsEmpty(nodes1))
4803 return(xmlXPathNodeSetCreate(
NULL));
4804 xmlXPathNodeSetSort(nodes1);
4805 xmlXPathNodeSetSort(nodes2);
4806 return(xmlXPathNodeTrailingSorted(nodes1,
4807 xmlXPathNodeSetItem(nodes2, 0)));
4827xmlXPathRegisterFunc(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4828 xmlXPathFunction
f) {
4829 return(xmlXPathRegisterFuncNS(ctxt,
name,
NULL,
f));
4844xmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4845 const xmlChar *ns_uri, xmlXPathFunction
f) {
4851 if (ctxt->funcHash ==
NULL)
4853 if (ctxt->funcHash ==
NULL)
4871xmlXPathRegisterFuncLookup (xmlXPathContextPtr ctxt,
4872 xmlXPathFuncLookupFunc
f,
4876 ctxt->funcLookupFunc =
f;
4877 ctxt->funcLookupData = funcCtxt;
4891xmlXPathFunctionLookup(xmlXPathContextPtr ctxt,
const xmlChar *
name) {
4895 if (ctxt->funcLookupFunc !=
NULL) {
4896 xmlXPathFunction
ret;
4897 xmlXPathFuncLookupFunc
f;
4899 f = ctxt->funcLookupFunc;
4904 return(xmlXPathFunctionLookupNS(ctxt,
name,
NULL));
4919xmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4921 xmlXPathFunction
ret;
4928 if (ctxt->funcLookupFunc !=
NULL) {
4929 xmlXPathFuncLookupFunc
f;
4931 f = ctxt->funcLookupFunc;
4932 ret =
f(ctxt->funcLookupData,
name, ns_uri);
4937 if (ctxt->funcHash ==
NULL)
4953xmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
4958 ctxt->funcHash =
NULL;
4979xmlXPathRegisterVariable(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4980 xmlXPathObjectPtr
value) {
4981 return(xmlXPathRegisterVariableNS(ctxt,
name,
NULL,
value));
4997xmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
4999 xmlXPathObjectPtr
value) {
5005 if (ctxt->varHash ==
NULL)
5007 if (ctxt->varHash ==
NULL)
5011 xmlXPathFreeObjectEntry));
5013 (
void *)
value, xmlXPathFreeObjectEntry));
5025xmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
5026 xmlXPathVariableLookupFunc
f,
void *
data) {
5029 ctxt->varLookupFunc =
f;
5030 ctxt->varLookupData =
data;
5044xmlXPathVariableLookup(xmlXPathContextPtr ctxt,
const xmlChar *
name) {
5048 if (ctxt->varLookupFunc !=
NULL) {
5049 xmlXPathObjectPtr
ret;
5051 ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
5055 return(xmlXPathVariableLookupNS(ctxt,
name,
NULL));
5070xmlXPathVariableLookupNS(xmlXPathContextPtr ctxt,
const xmlChar *
name,
5075 if (ctxt->varLookupFunc !=
NULL) {
5076 xmlXPathObjectPtr
ret;
5078 ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
5079 (ctxt->varLookupData,
name, ns_uri);
5083 if (ctxt->varHash ==
NULL)
5088 return(xmlXPathCacheObjectCopy(ctxt, (xmlXPathObjectPtr)
5099xmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
5103 xmlHashFree(ctxt->varHash, xmlXPathFreeObjectEntry);
5104 ctxt->varHash =
NULL;
5119xmlXPathRegisterNs(xmlXPathContextPtr ctxt,
const xmlChar *prefix,
5128 if (ctxt->nsHash ==
NULL)
5130 if (ctxt->nsHash ==
NULL)
5150xmlXPathNsLookup(xmlXPathContextPtr ctxt,
const xmlChar *prefix) {
5156#ifdef XML_XML_NAMESPACE
5161 if (ctxt->namespaces !=
NULL) {
5164 for (
i = 0;
i < ctxt->nsNr;
i++) {
5165 if ((ctxt->namespaces[
i] !=
NULL) &&
5167 return(ctxt->namespaces[
i]->href);
5181xmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
5186 ctxt->nsHash =
NULL;
5206xmlXPathNewFloat(
double val) {
5207 xmlXPathObjectPtr
ret;
5209 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5211 xmlXPathErrMemory(
NULL,
"creating float object\n");
5214 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5215 ret->type = XPATH_NUMBER;
5217#ifdef XP_DEBUG_OBJ_USAGE
5218 xmlXPathDebugObjUsageRequested(
NULL, XPATH_NUMBER);
5232xmlXPathNewBoolean(
int val) {
5233 xmlXPathObjectPtr
ret;
5235 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5237 xmlXPathErrMemory(
NULL,
"creating boolean object\n");
5240 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5241 ret->type = XPATH_BOOLEAN;
5242 ret->boolval = (
val != 0);
5243#ifdef XP_DEBUG_OBJ_USAGE
5244 xmlXPathDebugObjUsageRequested(
NULL, XPATH_BOOLEAN);
5259 xmlXPathObjectPtr
ret;
5261 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5263 xmlXPathErrMemory(
NULL,
"creating string object\n");
5266 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5267 ret->type = XPATH_STRING;
5272#ifdef XP_DEBUG_OBJ_USAGE
5273 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5288 xmlXPathObjectPtr
ret;
5290 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5292 xmlXPathErrMemory(
NULL,
"creating string object\n");
5295 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5296 ret->type = XPATH_STRING;
5298#ifdef XP_DEBUG_OBJ_USAGE
5299 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5313xmlXPathNewCString(
const char *
val) {
5314 xmlXPathObjectPtr
ret;
5316 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5318 xmlXPathErrMemory(
NULL,
"creating string object\n");
5321 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5322 ret->type = XPATH_STRING;
5324#ifdef XP_DEBUG_OBJ_USAGE
5325 xmlXPathDebugObjUsageRequested(
NULL, XPATH_STRING);
5339xmlXPathWrapCString (
char *
val) {
5340 return(xmlXPathWrapString((
xmlChar *)(
val)));
5352xmlXPathWrapExternal (
void *
val) {
5353 xmlXPathObjectPtr
ret;
5355 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5357 xmlXPathErrMemory(
NULL,
"creating user object\n");
5360 memset(
ret, 0 , (
size_t)
sizeof(xmlXPathObject));
5361 ret->type = XPATH_USERS;
5363#ifdef XP_DEBUG_OBJ_USAGE
5364 xmlXPathDebugObjUsageRequested(
NULL, XPATH_USERS);
5378xmlXPathObjectCopy(xmlXPathObjectPtr
val) {
5379 xmlXPathObjectPtr
ret;
5384 ret = (xmlXPathObjectPtr)
xmlMalloc(
sizeof(xmlXPathObject));
5386 xmlXPathErrMemory(
NULL,
"copying object\n");
5390#ifdef XP_DEBUG_OBJ_USAGE
5391 xmlXPathDebugObjUsageRequested(
NULL,
val->type);
5393 switch (
val->type) {
5396#ifdef LIBXML_XPTR_LOCS_ENABLED
5404 case XPATH_XSLT_TREE:
5411 if ((
val->nodesetval !=
NULL) &&
5412 (
val->nodesetval->nodeTab !=
NULL)) {
5418 top->name = (
char *)
5423 cur =
val->nodesetval->nodeTab[0]->children;
5433 ret->nodesetval = xmlXPathNodeSetCreate(
NULL);
5439 ret->nodesetval = xmlXPathNodeSetMerge(
NULL,
val->nodesetval);
5443#ifdef LIBXML_XPTR_LOCS_ENABLED
5444 case XPATH_LOCATIONSET:
5446 xmlLocationSetPtr loc =
val->user;
5447 ret->user = (
void *) xmlXPtrLocationSetMerge(
NULL, loc);
5454 case XPATH_UNDEFINED:
5456 "xmlXPathObjectCopy: unsupported type %d\n",
5470xmlXPathFreeObject(xmlXPathObjectPtr
obj) {
5472 if ((
obj->type == XPATH_NODESET) || (
obj->type == XPATH_XSLT_TREE)) {
5476 xmlXPathFreeNodeSet(
obj->nodesetval);
5480 obj->type = XPATH_XSLT_TREE;
5482 xmlXPathFreeValueTree(
obj->nodesetval);
5485 xmlXPathFreeNodeSet(
obj->nodesetval);
5487#ifdef LIBXML_XPTR_LOCS_ENABLED
5488 }
else if (
obj->type == XPATH_LOCATIONSET) {
5490 xmlXPtrFreeLocationSet(
obj->user);
5492 }
else if (
obj->type == XPATH_STRING) {
5496#ifdef XP_DEBUG_OBJ_USAGE
5497 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
5504 xmlXPathFreeObject((xmlXPathObjectPtr)
obj);
5515xmlXPathReleaseObject(xmlXPathContextPtr ctxt, xmlXPathObjectPtr
obj)
5517#define XP_CACHE_ADD(sl, o) if (sl == NULL) { \
5518 sl = xmlPointerListCreate(10); if (sl == NULL) goto free_obj; } \
5519 if (xmlPointerListAddSize(sl, obj, 0) == -1) goto free_obj;
5521#define XP_CACHE_WANTS(sl, n) ((sl == NULL) || ((sl)->number < n))
5525 if ((ctxt ==
NULL) || (ctxt->cache ==
NULL)) {
5526 xmlXPathFreeObject(
obj);
5528 xmlXPathContextCachePtr
cache =
5529 (xmlXPathContextCachePtr) ctxt->cache;
5533 case XPATH_XSLT_TREE:
5534 if (
obj->nodesetval !=
NULL) {
5541 obj->type = XPATH_XSLT_TREE;
5542 xmlXPathFreeValueTree(
obj->nodesetval);
5544 }
else if ((
obj->nodesetval->nodeMax <= 40) &&
5545 (XP_CACHE_WANTS(
cache->nodesetObjs,
5546 cache->maxNodeset)))
5548 XP_CACHE_ADD(
cache->nodesetObjs,
obj);
5551 xmlXPathFreeNodeSet(
obj->nodesetval);
5560 if (XP_CACHE_WANTS(
cache->stringObjs,
cache->maxString)) {
5561 XP_CACHE_ADD(
cache->stringObjs,
obj);
5566 if (XP_CACHE_WANTS(
cache->booleanObjs,
cache->maxBoolean)) {
5567 XP_CACHE_ADD(
cache->booleanObjs,
obj);
5572 if (XP_CACHE_WANTS(
cache->numberObjs,
cache->maxNumber)) {
5573 XP_CACHE_ADD(
cache->numberObjs,
obj);
5577#ifdef LIBXML_XPTR_LOCS_ENABLED
5578 case XPATH_LOCATIONSET:
5580 xmlXPtrFreeLocationSet(
obj->user);
5591 if (XP_CACHE_WANTS(
cache->miscObjs,
cache->maxMisc)) {
5592 XP_CACHE_ADD(
cache->miscObjs,
obj);
5598#ifdef XP_DEBUG_OBJ_USAGE
5599 xmlXPathDebugObjUsageReleased(ctxt,
obj->type);
5602 if (
obj->nodesetval !=
NULL) {
5603 xmlNodeSetPtr tmpset =
obj->nodesetval;
5611 if (tmpset->nodeNr > 1) {
5615 for (
i = 0;
i < tmpset->nodeNr;
i++) {
5616 node = tmpset->nodeTab[
i];
5623 }
else if (tmpset->nodeNr == 1) {
5624 if ((tmpset->nodeTab[0] !=
NULL) &&
5626 xmlXPathNodeSetFreeNs((
xmlNsPtr) tmpset->nodeTab[0]);
5630 obj->nodesetval = tmpset;
5641 xmlXPathFreeNodeSet(
obj->nodesetval);
5642#ifdef XP_DEBUG_OBJ_USAGE
5643 xmlXPathDebugObjUsageReleased(
NULL,
obj->type);
5666xmlXPathCastBooleanToString (
int val) {
5684xmlXPathCastNumberToString (
double val) {
5686 switch (xmlXPathIsInf(
val)) {
5694 if (xmlXPathIsNaN(
val)) {
5696 }
else if (
val == 0) {
5702 xmlXPathFormatNumber(
val,
buf, 99);
5735xmlXPathCastNodeSetToString (xmlNodeSetPtr
ns) {
5740 xmlXPathNodeSetSort(
ns);
5741 return(xmlXPathCastNodeToString(
ns->nodeTab[0]));
5754xmlXPathCastToString(xmlXPathObjectPtr
val) {
5759 switch (
val->type) {
5760 case XPATH_UNDEFINED:
5767 case XPATH_XSLT_TREE:
5768 ret = xmlXPathCastNodeSetToString(
val->nodesetval);
5773 ret = xmlXPathCastBooleanToString(
val->boolval);
5775 case XPATH_NUMBER: {
5776 ret = xmlXPathCastNumberToString(
val->floatval);
5780#ifdef LIBXML_XPTR_LOCS_ENABLED
5783 case XPATH_LOCATIONSET:
5802xmlXPathConvertString(xmlXPathObjectPtr
val) {
5806 return(xmlXPathNewCString(
""));
5808 switch (
val->type) {
5809 case XPATH_UNDEFINED:
5815 case XPATH_XSLT_TREE:
5816 res = xmlXPathCastNodeSetToString(
val->nodesetval);
5821 res = xmlXPathCastBooleanToString(
val->boolval);
5824 res = xmlXPathCastNumberToString(
val->floatval);
5827#ifdef LIBXML_XPTR_LOCS_ENABLED
5830 case XPATH_LOCATIONSET:
5835 xmlXPathFreeObject(
val);
5837 return(xmlXPathNewCString(
""));
5838 return(xmlXPathWrapString(
res));
5850xmlXPathCastBooleanToNumber(
int val) {
5865xmlXPathCastStringToNumber(
const xmlChar *
val) {
5883 return(xmlXPathNAN);
5886 return(xmlXPathNAN);
5887 ret = xmlXPathCastStringToNumber(
strval);
5902xmlXPathCastNodeSetToNumber (xmlNodeSetPtr
ns) {
5907 return(xmlXPathNAN);
5908 str = xmlXPathCastNodeSetToString(
ns);
5909 ret = xmlXPathCastStringToNumber(
str);
5923xmlXPathCastToNumber(xmlXPathObjectPtr
val) {
5927 return(xmlXPathNAN);
5928 switch (
val->type) {
5929 case XPATH_UNDEFINED:
5936 case XPATH_XSLT_TREE:
5937 ret = xmlXPathCastNodeSetToNumber(
val->nodesetval);
5940 ret = xmlXPathCastStringToNumber(
val->stringval);
5946 ret = xmlXPathCastBooleanToNumber(
val->boolval);
5949#ifdef LIBXML_XPTR_LOCS_ENABLED
5952 case XPATH_LOCATIONSET:
5971xmlXPathConvertNumber(xmlXPathObjectPtr
val) {
5972 xmlXPathObjectPtr
ret;
5975 return(xmlXPathNewFloat(0.0));
5976 if (
val->type == XPATH_NUMBER)
5978 ret = xmlXPathNewFloat(xmlXPathCastToNumber(
val));
5979 xmlXPathFreeObject(
val);
5992xmlXPathCastNumberToBoolean (
double val) {
5993 if (xmlXPathIsNaN(
val) || (
val == 0.0))
6007xmlXPathCastStringToBoolean (
const xmlChar *
val) {
6022xmlXPathCastNodeSetToBoolean (xmlNodeSetPtr
ns) {
6023 if ((
ns ==
NULL) || (
ns->nodeNr == 0))
6037xmlXPathCastToBoolean (xmlXPathObjectPtr
val) {
6042 switch (
val->type) {