443 iter.base.current = cx_tree_visitor_current; |
443 iter.base.current = cx_tree_visitor_current; |
444 |
444 |
445 return iter; |
445 return iter; |
446 } |
446 } |
447 |
447 |
|
448 static void cx_tree_add_link_duplicate( |
|
449 void **root, void *original, void *duplicate, |
|
450 ptrdiff_t loc_parent, ptrdiff_t loc_children, ptrdiff_t loc_last_child, |
|
451 ptrdiff_t loc_prev, ptrdiff_t loc_next |
|
452 ) { |
|
453 cx_tree_zero_pointers(duplicate, cx_tree_ptr_locations); |
|
454 void *shared_parent = tree_parent(original); |
|
455 if (shared_parent == NULL) { |
|
456 cx_tree_link(duplicate, original, cx_tree_ptr_locations); |
|
457 *root = duplicate; |
|
458 } else { |
|
459 cx_tree_link(shared_parent, duplicate, cx_tree_ptr_locations); |
|
460 } |
|
461 } |
|
462 |
448 void *cx_tree_add( |
463 void *cx_tree_add( |
449 void const *src, |
464 void const *src, |
450 cx_tree_search_func sfunc, |
465 cx_tree_search_func sfunc, |
451 cx_tree_node_create_func cfunc, |
466 cx_tree_node_create_func cfunc, |
452 void *cdata, |
467 void *cdata, |
481 node = cfunc(src, NULL, cdata); |
496 node = cfunc(src, NULL, cdata); |
482 if (node == NULL) return NULL; |
497 if (node == NULL) return NULL; |
483 cx_tree_zero_pointers(node, cx_tree_ptr_locations); |
498 cx_tree_zero_pointers(node, cx_tree_ptr_locations); |
484 cx_tree_link(node, *root, cx_tree_ptr_locations); |
499 cx_tree_link(node, *root, cx_tree_ptr_locations); |
485 *root = node; |
500 *root = node; |
486 return node; |
|
487 } else if (result == 0) { |
501 } else if (result == 0) { |
488 // data already found in the tree, let cfunc decide |
502 // data already found in the tree, let cfunc decide |
489 node = cfunc(src, match, cdata); |
503 node = cfunc(src, match, cdata); |
490 if (node == NULL) return NULL; |
504 if (node == NULL) return NULL; |
491 if (node != match) { |
505 if (node != match) { |
492 cx_tree_zero_pointers(node, cx_tree_ptr_locations); |
506 cx_tree_add_link_duplicate( |
493 cx_tree_link(match, node, cx_tree_ptr_locations); |
507 root, match, node, cx_tree_ptr_locations); |
494 } |
508 } |
495 } else { |
509 } else { |
496 // closest match found, add new node as child |
510 // closest match found, add new node as child |
497 node = cfunc(src, NULL, cdata); |
511 node = cfunc(src, NULL, cdata); |
498 if (node == NULL) return NULL; |
512 if (node == NULL) return NULL; |
578 } else if (result == 0) { |
592 } else if (result == 0) { |
579 // data already found in the tree, let cfunc decide |
593 // data already found in the tree, let cfunc decide |
580 node = cfunc(elem, match, cdata); |
594 node = cfunc(elem, match, cdata); |
581 if (node == NULL) return processed; |
595 if (node == NULL) return processed; |
582 if (node != match) { |
596 if (node != match) { |
583 cx_tree_zero_pointers(node, cx_tree_ptr_locations); |
597 cx_tree_add_link_duplicate( |
584 cx_tree_link(match, node, cx_tree_ptr_locations); |
598 root, match, node, cx_tree_ptr_locations); |
585 } |
599 } |
586 current_node = node; |
600 current_node = node; |
587 } else { |
601 } else { |
588 // closest match found, add new node as child |
602 // closest match found, add new node as child |
589 node = cfunc(elem, NULL, cdata); |
603 node = cfunc(elem, NULL, cdata); |