// File: /workspace/github_c_makefile_star2_O3/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 %rbx
testq %rdi, %rdi
je 0x7b06
movq %rdi, %r14
movq 0x8(%rdi), %rdi
callq 0x79b8
movq %rax, %rbx
testq %rax, %rax
je 0x7afd
movq (%r14), %rax
testq %rax, %rax
je 0x7afd
movq 0x8(%rax), %rcx
testq %rcx, %rcx
je 0x7a71
movq %rcx, %r15
movq %rcx, %rdx
movq %rdx, %rcx
movq 0x10(%rdx), %rdx
testq %rdx, %rdx
jne 0x7a53
movq %rax, 0x10(%rcx)
movq 0x8(%r15), %rcx
movq %r15, %rax
testq %rcx, %rcx
jne 0x7a4d
jmp 0x7a74
movq %rax, %r15
movl $0x18, %edi
callq 0x10d0
movq %rax, (%rbx)
testq %rax, %rax
je 0x7af8
movq %rax, %r14
movq (%r15), %rax
movq %rax, (%r14)
xorps %xmm0, %xmm0
movups %xmm0, 0x8(%r14)
movq 0x10(%r15), %rax
testq %rax, %rax
je 0x7afd
movq 0x8(%rax), %rcx
testq %rcx, %rcx
je 0x7adf
movq %rcx, %r15
movq %rcx, %rdx
movq %rdx, %rcx
movq 0x10(%rdx), %rdx
testq %rdx, %rdx
je 0x7ac0
cmpq %rax, %rdx
jne 0x7aaf
testq %rdx, %rdx
jne 0x7ad7
movq %rax, 0x10(%rcx)
movq 0x8(%r15), %rcx
movq %r15, %rax
testq %rcx, %rcx
jne 0x7aa9
jmp 0x7ae2
movq $0x0, 0x10(%rcx)
movq %rax, %r15
movl $0x18, %edi
callq 0x10d0
movq %rax, 0x10(%r14)
movq %rax, %r14
testq %rax, %rax
jne 0x7a89
callq 0x114c
movq %rbx, %rax
popq %rbx
popq %r14
popq %r15
retq
leaq 0x6776(%rip), %rdi      # 0xe283
leaq 0x66f9(%rip), %rsi      # 0xe20d
leaq 0x6775(%rip), %rcx      # 0xe290
movl $0x76, %edx
callq 0x1080