* xmlXPtrEval: * @str: the XPointer expression * @ctx: the XPointer context * * Evaluate the XPath Location Path in the given context. * * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL. * the caller has to free the object. */
| 1340 | * the caller has to free the object. |
| 1341 | */ |
| 1342 | xmlXPathObjectPtr |
| 1343 | xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) { |
| 1344 | xmlXPathParserContextPtr ctxt; |
| 1345 | xmlXPathObjectPtr res = NULL, tmp; |
| 1346 | xmlXPathObjectPtr init = NULL; |
| 1347 | int stack = 0; |
| 1348 | |
| 1349 | xmlInitParser(); |
| 1350 | |
| 1351 | if ((ctx == NULL) || (str == NULL)) |
| 1352 | return(NULL); |
| 1353 | |
| 1354 | xmlResetError(&ctx->lastError); |
| 1355 | |
| 1356 | ctxt = xmlXPathNewParserContext(str, ctx); |
| 1357 | if (ctxt == NULL) { |
| 1358 | xmlXPathErrMemory(ctx); |
| 1359 | return(NULL); |
| 1360 | } |
| 1361 | xmlXPtrEvalXPointer(ctxt); |
| 1362 | if (ctx->lastError.code != XML_ERR_OK) |
| 1363 | goto error; |
| 1364 | |
| 1365 | if ((ctxt->value != NULL) && |
| 1366 | #ifdef LIBXML_XPTR_LOCS_ENABLED |
| 1367 | (ctxt->value->type != XPATH_LOCATIONSET) && |
| 1368 | #endif |
| 1369 | (ctxt->value->type != XPATH_NODESET)) { |
| 1370 | xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED, |
| 1371 | "xmlXPtrEval: evaluation failed to return a node set\n", |
| 1372 | NULL); |
| 1373 | } else { |
| 1374 | res = valuePop(ctxt); |
| 1375 | } |
| 1376 | |
| 1377 | do { |
| 1378 | tmp = valuePop(ctxt); |
| 1379 | if (tmp != NULL) { |
| 1380 | if (tmp != init) { |
| 1381 | if (tmp->type == XPATH_NODESET) { |
| 1382 | /* |
| 1383 | * Evaluation may push a root nodeset which is unused |
| 1384 | */ |
| 1385 | xmlNodeSetPtr set; |
| 1386 | set = tmp->nodesetval; |
| 1387 | if ((set == NULL) || (set->nodeNr != 1) || |
| 1388 | (set->nodeTab[0] != (xmlNodePtr) ctx->doc)) |
| 1389 | stack++; |
| 1390 | } else |
| 1391 | stack++; |
| 1392 | } |
| 1393 | xmlXPathFreeObject(tmp); |
| 1394 | } |
| 1395 | } while (tmp != NULL); |
| 1396 | if (stack != 0) { |
| 1397 | xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS, |
| 1398 | "xmlXPtrEval: object(s) left on the eval stack\n", |
| 1399 | NULL); |
no test coverage detected