// File: /workspace/github_c_makefile_star2_O0/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 %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0xc675
jmp 0xc694
leaq 0x9bf6(%rip), %rdi      # 0x16272
leaq 0x9b79(%rip), %rsi      # 0x161fc
movl $0x76, %edx
leaq 0x9bf0(%rip), %rcx      # 0x1627f
callq 0x1060
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xc5c0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xc6b9
movq $0x0, -0x8(%rbp)
jmp 0xc871
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0xc719
jmp 0xc6cd
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0xc717
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0xc6fd
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0xc6e4
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0xc6cd
jmp 0xc719
jmp 0xc71b
cmpq $0x0, -0x30(%rbp)
je 0xc869
cmpq $0x0, -0x20(%rbp)
jne 0xc74e
movl $0x18, %edi
callq 0x10a0
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0xc76f
movl $0x18, %edi
callq 0x10a0
movq %rax, %rcx
movq -0x20(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0xc79b
movq 0xd87b(%rip), %rax      # 0x19ff8
movq (%rax), %rdi
leaq 0x9b1f(%rip), %rsi      # 0x162a6
movb $0x0, %al
callq 0x1080
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc871
movq -0x30(%rbp), %rax
movq (%rax), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x20(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0xc864
jmp 0xc7da
movq -0x30(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0xc862
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rcx
xorl %eax, %eax
cmpq $0x0, 0x10(%rcx)
movb %al, -0x31(%rbp)
je 0xc813
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x30(%rbp), %rax
setne %al
movb %al, -0x31(%rbp)
movb -0x31(%rbp), %al
testb $0x1, %al
jne 0xc81c
jmp 0xc82a
movq -0x28(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0xc7f1
movq -0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0xc84f
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0xc85d
movq -0x28(%rbp), %rax
movq $0x0, 0x10(%rax)
jmp 0xc862
jmp 0xc7da
jmp 0xc864
jmp 0xc71b
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)