* xmlXPathCompFunctionCall: * @ctxt: the XPath Parser context * * [16] FunctionCall ::= FunctionName '(' ( Argument ( ',' Argument)*)? ')' * [17] Argument ::= Expr * * Compile a function call, the evaluation of all arguments are * pushed on the stack */
| 9348 | * pushed on the stack |
| 9349 | */ |
| 9350 | static void |
| 9351 | xmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) { |
| 9352 | xmlChar *name; |
| 9353 | xmlChar *prefix; |
| 9354 | int nbargs = 0; |
| 9355 | int sort = 1; |
| 9356 | |
| 9357 | name = xmlXPathParseQName(ctxt, &prefix); |
| 9358 | if (name == NULL) { |
| 9359 | xmlFree(prefix); |
| 9360 | XP_ERROR(XPATH_EXPR_ERROR); |
| 9361 | } |
| 9362 | SKIP_BLANKS; |
| 9363 | |
| 9364 | if (CUR != '(') { |
| 9365 | xmlFree(name); |
| 9366 | xmlFree(prefix); |
| 9367 | XP_ERROR(XPATH_EXPR_ERROR); |
| 9368 | } |
| 9369 | NEXT; |
| 9370 | SKIP_BLANKS; |
| 9371 | |
| 9372 | /* |
| 9373 | * Optimization for count(): we don't need the node-set to be sorted. |
| 9374 | */ |
| 9375 | if ((prefix == NULL) && (name[0] == 'c') && |
| 9376 | xmlStrEqual(name, BAD_CAST "count")) |
| 9377 | { |
| 9378 | sort = 0; |
| 9379 | } |
| 9380 | ctxt->comp->last = -1; |
| 9381 | if (CUR != ')') { |
| 9382 | while (CUR != 0) { |
| 9383 | int op1 = ctxt->comp->last; |
| 9384 | ctxt->comp->last = -1; |
| 9385 | xmlXPathCompileExpr(ctxt, sort); |
| 9386 | if (ctxt->error != XPATH_EXPRESSION_OK) { |
| 9387 | xmlFree(name); |
| 9388 | xmlFree(prefix); |
| 9389 | return; |
| 9390 | } |
| 9391 | PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0); |
| 9392 | nbargs++; |
| 9393 | if (CUR == ')') break; |
| 9394 | if (CUR != ',') { |
| 9395 | xmlFree(name); |
| 9396 | xmlFree(prefix); |
| 9397 | XP_ERROR(XPATH_EXPR_ERROR); |
| 9398 | } |
| 9399 | NEXT; |
| 9400 | SKIP_BLANKS; |
| 9401 | } |
| 9402 | } |
| 9403 | if (PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0, name, prefix) == -1) { |
| 9404 | xmlFree(prefix); |
| 9405 | xmlFree(name); |
| 9406 | } |
| 9407 | NEXT; |
no test coverage detected