// File: /workspace/github_c_makefile_star2_O2/CarlosLunaMota[P]BinaryTrees/BinaryTrees.c
// Function: bs_tree_copy
bs_tree *bs_tree_copy(const bs_tree *tree) {

    bs_tree *new_tree = NULL;
    bs_node *new_node = NULL;
    bs_node *pred;
    bs_node *node;
    
    // Sanity check:
    assert(tree != NULL);
    
    // Create a new tree:
    new_tree = new_bs_tree(tree->comp);
    if (new_tree == NULL) { return NULL; }

    // Go to the smallest element of tree while right-threading your path:
    node = tree->root;
    if (node != NULL) {
        while (node->left != NULL) {
            pred = node->left;
            while (pred->right != NULL) { pred = pred->right; }
            pred->right = node;
            node        = node->left;
        }
    }

    // Insert all data from tree into new_tree:
    while (node != NULL) {

        // insert node->data in new_tree ///////////////////////////////////////
        if (new_node == NULL)  {
            new_tree->root = (bs_node *) malloc(sizeof(bs_node));
            new_node = new_tree->root;
        } else {
            new_node->right = (bs_node *) malloc(sizeof(bs_node));
            new_node = new_node->right;
        }
        if (new_node == NULL) {
            fprintf(stderr, "ERROR: Unable to allocate bs_node\n");
            return new_tree;
        } else {
            new_node->data  = node->data;
            new_node->left  = NULL;
            new_node->right = NULL;
        }
        ////////////////////////////////////////////////////////////////////////

        // advance node ////////////////////////////////////////////////////////
        node = node->right;
        if (node != NULL) {
            while (node->left != NULL) {
                pred = node->left;
                while (pred->right != NULL && pred->right != node) {
                    pred = pred->right;
                }
                if (pred->right == NULL) {
                    pred->right = node;
                    node        = node->left;
                } else {
                    pred->right = NULL;
                    break;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////
    }

    // Return the resulting tree:
    return new_tree;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x752d
movq %rdi, %r14
movq 0x8(%rdi), %rdi
callq 0x73c0
movq %rax, %rbx
testq %rax, %rax
je 0x751e
movq (%r14), %r15
testq %r15, %r15
je 0x747c
movq 0x8(%r15), %rax
testq %rax, %rax
je 0x747f
movq %rax, %rdx
movq %rdx, %rcx
movq 0x10(%rdx), %rdx
testq %rdx, %rdx
jne 0x7467
movq %r15, 0x10(%rcx)
movq %rax, %r15
jmp 0x745b
xorl %r15d, %r15d
xorl %r12d, %r12d
pushq $0x18
popq %r14
testq %r15, %r15
je 0x751e
movq %r14, %rdi
callq 0x10d0
leaq 0x10(%r12), %rcx
testq %r12, %r12
cmoveq %rbx, %rcx
movq %rax, (%rcx)
testq %rax, %rax
je 0x7502
movq (%r15), %rcx
movq %rcx, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%rax)
movq 0x10(%r15), %rcx
movq %rax, %r12
movl $0x0, %r15d
testq %rcx, %rcx
je 0x7486
movq 0x8(%rcx), %rdx
testq %rdx, %rdx
je 0x74fa
movq %rdx, %rdi
movq %rdi, %rsi
movq 0x10(%rdi), %rdi
testq %rdi, %rdi
je 0x74e7
cmpq %rcx, %rdi
jne 0x74d6
testq %rdi, %rdi
jne 0x74f5
movq %rcx, 0x10(%rsi)
movq %rdx, %rcx
jmp 0x74ca
andq $0x0, 0x10(%rsi)
movq %rax, %r12
movq %rcx, %r15
jmp 0x7486
movq 0x9aef(%rip), %rax      # 0x10ff8
movq (%rax), %rcx
leaq 0x5da4(%rip), %rdi      # 0xd2b7
pushq $0x22
popq %rsi
pushq $0x1
popq %rdx
callq 0x1100
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x5d4f(%rip), %rdi      # 0xd283
leaq 0x5cd2(%rip), %rsi      # 0xd20d
leaq 0x5d4e(%rip), %rcx      # 0xd290
pushq $0x76
popq %rdx
callq 0x1080