* xmlXPathCmpNodesExt: * @node1: the first node * @node2: the second node * * Compare two nodes w.r.t document order. * This one is optimized for handling of non-element nodes. * * Returns -2 in case of error 1 if first point < second point, 0 if * it's the same node, -1 otherwise */
| 257 | * it's the same node, -1 otherwise |
| 258 | */ |
| 259 | static int |
| 260 | xmlXPathCmpNodesExt(xmlNodePtr node1, xmlNodePtr node2) { |
| 261 | int depth1, depth2; |
| 262 | int misc = 0, precedence1 = 0, precedence2 = 0; |
| 263 | xmlNodePtr miscNode1 = NULL, miscNode2 = NULL; |
| 264 | xmlNodePtr cur, root; |
| 265 | ptrdiff_t l1, l2; |
| 266 | |
| 267 | if ((node1 == NULL) || (node2 == NULL)) |
| 268 | return(-2); |
| 269 | |
| 270 | if (node1 == node2) |
| 271 | return(0); |
| 272 | |
| 273 | /* |
| 274 | * a couple of optimizations which will avoid computations in most cases |
| 275 | */ |
| 276 | switch (node1->type) { |
| 277 | case XML_ELEMENT_NODE: |
| 278 | if (node2->type == XML_ELEMENT_NODE) { |
| 279 | if ((0 > (ptrdiff_t) node1->content) && |
| 280 | (0 > (ptrdiff_t) node2->content) && |
| 281 | (node1->doc == node2->doc)) |
| 282 | { |
| 283 | l1 = -((ptrdiff_t) node1->content); |
| 284 | l2 = -((ptrdiff_t) node2->content); |
| 285 | if (l1 < l2) |
| 286 | return(1); |
| 287 | if (l1 > l2) |
| 288 | return(-1); |
| 289 | } else |
| 290 | goto turtle_comparison; |
| 291 | } |
| 292 | break; |
| 293 | case XML_ATTRIBUTE_NODE: |
| 294 | precedence1 = 1; /* element is owner */ |
| 295 | miscNode1 = node1; |
| 296 | node1 = node1->parent; |
| 297 | misc = 1; |
| 298 | break; |
| 299 | case XML_TEXT_NODE: |
| 300 | case XML_CDATA_SECTION_NODE: |
| 301 | case XML_COMMENT_NODE: |
| 302 | case XML_PI_NODE: { |
| 303 | miscNode1 = node1; |
| 304 | /* |
| 305 | * Find nearest element node. |
| 306 | */ |
| 307 | if (node1->prev != NULL) { |
| 308 | do { |
| 309 | node1 = node1->prev; |
| 310 | if (node1->type == XML_ELEMENT_NODE) { |
| 311 | precedence1 = 3; /* element in prev-sibl axis */ |
| 312 | break; |
| 313 | } |
| 314 | if (node1->prev == NULL) { |
| 315 | precedence1 = 2; /* element is parent */ |
| 316 | /* |
no outgoing calls
no test coverage detected