* xmlXPathCompileExpr: * @ctxt: the XPath Parser context * * [14] Expr ::= OrExpr * [21] OrExpr ::= AndExpr * | OrExpr 'or' AndExpr * * Parse and compile an expression */
| 9909 | * Parse and compile an expression |
| 9910 | */ |
| 9911 | static void |
| 9912 | xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) { |
| 9913 | xmlXPathContextPtr xpctxt = ctxt->context; |
| 9914 | |
| 9915 | if (xpctxt != NULL) { |
| 9916 | if (xpctxt->depth >= XPATH_MAX_RECURSION_DEPTH) |
| 9917 | XP_ERROR(XPATH_RECURSION_LIMIT_EXCEEDED); |
| 9918 | /* |
| 9919 | * Parsing a single '(' pushes about 10 functions on the call stack |
| 9920 | * before recursing! |
| 9921 | */ |
| 9922 | xpctxt->depth += 10; |
| 9923 | } |
| 9924 | |
| 9925 | xmlXPathCompAndExpr(ctxt); |
| 9926 | CHECK_ERROR; |
| 9927 | SKIP_BLANKS; |
| 9928 | while ((CUR == 'o') && (NXT(1) == 'r')) { |
| 9929 | int op1 = ctxt->comp->last; |
| 9930 | SKIP(2); |
| 9931 | SKIP_BLANKS; |
| 9932 | xmlXPathCompAndExpr(ctxt); |
| 9933 | CHECK_ERROR; |
| 9934 | PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0); |
| 9935 | SKIP_BLANKS; |
| 9936 | } |
| 9937 | if ((sort) && (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE)) { |
| 9938 | /* more ops could be optimized too */ |
| 9939 | /* |
| 9940 | * This is the main place to eliminate sorting for |
| 9941 | * operations which don't require a sorted node-set. |
| 9942 | * E.g. count(). |
| 9943 | */ |
| 9944 | PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0); |
| 9945 | } |
| 9946 | |
| 9947 | if (xpctxt != NULL) |
| 9948 | xpctxt->depth -= 10; |
| 9949 | } |
| 9950 | |
| 9951 | /** |
| 9952 | * xmlXPathCompPredicate: |
no test coverage detected