// File: /workspace/github_c_makefile_star2_O0/MaoKo[P]FGFX/fgfl/src/regex_node.c
// Function: remove_useless_epsilon
bool
remove_useless_epsilon(regex_node_t* root) {
    if (!root)
        { return (false); }

    switch (root->kind_ast) {
        case AST_DOT:
        case AST_SYMBOL:
        case AST_CLASS:
            return (false);

        case AST_EPSILON:
            return (true);

        case AST_UNION:
            if ((remove_useless_epsilon(root->left))
                    && (remove_useless_epsilon(root->right))) {

                del_regex_node(root->left);
                del_regex_node(root->right);

                root->kind_ast = AST_EPSILON;
                return (true);
            }
            else
                { return (false); }

        case AST_LOOK:
        case AST_CONCAT: ;
            bool left = remove_useless_epsilon(root->left);
            bool right = remove_useless_epsilon(root->right);

            if (left || right) {
                if (left)
                    { del_regex_node(root->left); }
                if (right)
                    { del_regex_node(root->right); }

                if (left && right) {
                    root->kind_ast = AST_EPSILON;
                    return (true);
                }
                else {
                    regex_node_t* src_node = NULL_NODE;
                    if (!left)
                        { src_node = root->left; }
                    else
                        { src_node = root->right; }
                    memcpy(root, src_node, sizeof(*src_node));
                    FREE(src_node);
                }
            }
            return (false);

        case AST_STAR:
        case AST_QUES:
        case AST_PLUS:
        case AST_TILDE:
        case AST_OPTION:
            if (remove_useless_epsilon(root->left)) {
                del_regex_node(root->left);
                root->kind_ast = AST_EPSILON;
                return (true);
            }
            else
                { return (false); }

        default:
            return (false);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0xa96c
movb $0x0, -0x1(%rbp)
jmp 0xab14
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x28(%rbp)
subq $0xc, %rax
ja 0xab10
movq -0x28(%rbp), %rax
leaq 0x4719(%rip), %rcx      # 0xf0a4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movb $0x0, -0x1(%rbp)
jmp 0xab14
movb $0x1, -0x1(%rbp)
jmp 0xab14
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa950
testb $0x1, %al
jne 0xa9b9
jmp 0xa9f9
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xa950
testb $0x1, %al
jne 0xa9cc
jmp 0xa9f9
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa380
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xa380
movq -0x10(%rbp), %rax
movl $0xb, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0xab14
movb $0x0, -0x1(%rbp)
jmp 0xab14
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa950
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xa950
andb $0x1, %al
movb %al, -0x12(%rbp)
testb $0x1, -0x11(%rbp)
jne 0xaa36
testb $0x1, -0x12(%rbp)
je 0xaad4
testb $0x1, -0x11(%rbp)
je 0xaa49
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa380
testb $0x1, -0x12(%rbp)
je 0xaa5c
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xa380
testb $0x1, -0x11(%rbp)
je 0xaa7b
testb $0x1, -0x12(%rbp)
je 0xaa7b
movq -0x10(%rbp), %rax
movl $0xb, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0xab14
movq $0x0, -0x20(%rbp)
testb $0x1, -0x11(%rbp)
jne 0xaa97
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0xaaa3
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq -0x20(%rbp), %rdi
callq 0x1030
jmp 0xaad4
movb $0x0, -0x1(%rbp)
jmp 0xab14
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa950
testb $0x1, %al
jne 0xaaed
jmp 0xab0a
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0xa380
movq -0x10(%rbp), %rax
movl $0xb, (%rax)
movb $0x1, -0x1(%rbp)
jmp 0xab14
movb $0x0, -0x1(%rbp)
jmp 0xab14
movb $0x0, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x30, %rsp
popq %rbp
retq
nop