* xmlXPathCmpNodes: * @node1: the first node * @node2: the second node * * Compare two nodes w.r.t document order * * Returns -2 in case of error 1 if first point < second point, 0 if * it's the same node, -1 otherwise */
| 2503 | * it's the same node, -1 otherwise |
| 2504 | */ |
| 2505 | int |
| 2506 | xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) { |
| 2507 | int depth1, depth2; |
| 2508 | int attr1 = 0, attr2 = 0; |
| 2509 | xmlNodePtr attrNode1 = NULL, attrNode2 = NULL; |
| 2510 | xmlNodePtr cur, root; |
| 2511 | |
| 2512 | if ((node1 == NULL) || (node2 == NULL)) |
| 2513 | return(-2); |
| 2514 | /* |
| 2515 | * a couple of optimizations which will avoid computations in most cases |
| 2516 | */ |
| 2517 | if (node1 == node2) /* trivial case */ |
| 2518 | return(0); |
| 2519 | if (node1->type == XML_ATTRIBUTE_NODE) { |
| 2520 | attr1 = 1; |
| 2521 | attrNode1 = node1; |
| 2522 | node1 = node1->parent; |
| 2523 | } |
| 2524 | if (node2->type == XML_ATTRIBUTE_NODE) { |
| 2525 | attr2 = 1; |
| 2526 | attrNode2 = node2; |
| 2527 | node2 = node2->parent; |
| 2528 | } |
| 2529 | if (node1 == node2) { |
| 2530 | if (attr1 == attr2) { |
| 2531 | /* not required, but we keep attributes in order */ |
| 2532 | if (attr1 != 0) { |
| 2533 | cur = attrNode2->prev; |
| 2534 | while (cur != NULL) { |
| 2535 | if (cur == attrNode1) |
| 2536 | return (1); |
| 2537 | cur = cur->prev; |
| 2538 | } |
| 2539 | return (-1); |
| 2540 | } |
| 2541 | return(0); |
| 2542 | } |
| 2543 | if (attr2 == 1) |
| 2544 | return(1); |
| 2545 | return(-1); |
| 2546 | } |
| 2547 | if ((node1->type == XML_NAMESPACE_DECL) || |
| 2548 | (node2->type == XML_NAMESPACE_DECL)) |
| 2549 | return(1); |
| 2550 | if (node1 == node2->prev) |
| 2551 | return(1); |
| 2552 | if (node1 == node2->next) |
| 2553 | return(-1); |
| 2554 | |
| 2555 | /* |
| 2556 | * Speedup using document order if available. |
| 2557 | */ |
| 2558 | if ((node1->type == XML_ELEMENT_NODE) && |
| 2559 | (node2->type == XML_ELEMENT_NODE) && |
| 2560 | (0 > (ptrdiff_t) node1->content) && |
| 2561 | (0 > (ptrdiff_t) node2->content) && |
| 2562 | (node1->doc == node2->doc)) { |
no outgoing calls
no test coverage detected