// File: /workspace/github_c_makefile_star2_O0/OhYee[P]computer_application_programming_experiment/utils/ac_automaton/test/test_ac_automaton.c
// Function: main
int main() {
    boolean pass = T;
    mp_init(1 << 20, mp_exit);

    char *         string = "aababbcabcaacca";
    char *         patterns[] = {"a", "ab", "bab", "bc", "bca", "c", "caa"};
    int            want[] = {7, 3, 1, 2, 2, 4, 1};
    int            length = sizeof(patterns) / sizeof(char *);
    ac_tree_node **nodes = mp_new(length * sizeof(ac_tree_node *));

    ac_automaton *ac = ac_init();
    for (int i = 0; i < length; ++i) {
        nodes[i] = ac_add(ac, patterns[i]);
    }
    ac_build(ac);

    // ac_print(ac);
    pass &= judge(ac->root,  ac->root);

    pass &= judge(ac->root->children['a'], ac->root);
    pass &=
        judge(ac->root->children['a']->children['b'], ac->root->children['b']);

    pass &= judge(ac->root->children['b'], ac->root);
    pass &=
        judge(ac->root->children['b']->children['a'], ac->root->children['a']);
    pass &= judge(ac->root->children['b']->children['a']->children['b'],
                  ac->root->children['a']->children['b']);

    pass &=
        judge(ac->root->children['b']->children['c'], ac->root->children['c']);
    pass &= judge(ac->root->children['b']->children['c']->children['a'],
                  ac->root->children['c']->children['a']);

    pass &= judge(ac->root->children['c'], ac->root);
    pass &=
        judge(ac->root->children['c']->children['a'], ac->root->children['a']);
    pass &= judge(ac->root->children['c']->children['a']->children['a'],
                  ac->root->children['a']);

    char *c = string;
    while (*c != '\0') {
        ac_match_char(ac, *c);
        ++c;
    }

    for (int i = 0; i < length; ++i) {
        if (want[i] != nodes[i]->match_number) {
            print_err("'%s' matchs %d times, but want %d times\n", patterns[i],
                      nodes[i]->match_number, want[i]);
            pass = F;
        }
    }

    if (pass) {
        print_ok("All testcases passed\n");
    } else {
        print_err("Some errors!\n");
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movl $0x0, -0x4(%rbp)
leaq 0xd5f(%rip), %rax       # 0x3028
movl (%rax), %eax
movl %eax, -0x8(%rbp)
movl $0x100000, %edi         # imm = 0x100000
leaq -0x73a(%rip), %rsi      # 0x1ba0
callq 0x1bb0
leaq 0xeb8(%rip), %rax       # 0x319e
movq %rax, -0x10(%rbp)
leaq -0x50(%rbp), %rdi
leaq 0x2abb(%rip), %rsi      # 0x4db0
movl $0x38, %edx
callq 0x1050
movq 0xf0a(%rip), %rax       # 0x3210
movq %rax, -0x70(%rbp)
movq 0xf07(%rip), %rax       # 0x3218
movq %rax, -0x68(%rbp)
movq 0xf04(%rip), %rax       # 0x3220
movq %rax, -0x60(%rbp)
movl 0xf02(%rip), %eax       # 0x3228
movl %eax, -0x58(%rbp)
movl $0x7, -0x74(%rbp)
movslq -0x74(%rbp), %rax
shlq $0x3, %rax
movl %eax, %edi
callq 0x1ec0
movq %rax, -0x80(%rbp)
movb $0x0, %al
callq 0x11d0
movq %rax, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
cmpl -0x74(%rbp), %eax
jge 0x23a1
movq -0x88(%rbp), %rdi
movslq -0x8c(%rbp), %rax
movq -0x50(%rbp,%rax,8), %rsi
callq 0x1290
movq %rax, %rdx
movq -0x80(%rbp), %rax
movslq -0x8c(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x235b
movq -0x88(%rbp), %rdi
callq 0x13a0
movq -0x88(%rbp), %rax
movq (%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x310(%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x318(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rsi
callq 0x2250
andl -0x8(%rbp), %eax
movl %eax, -0x8(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x2668
movq -0x88(%rbp), %rdi
movq -0x98(%rbp), %rax
movsbl (%rax), %esi
callq 0x1590
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x262f
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
cmpl -0x74(%rbp), %eax
jge 0x26f2
movslq -0x9c(%rbp), %rax
movl -0x70(%rbp,%rax,4), %eax
movq -0x80(%rbp), %rcx
movslq -0x9c(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
cmpl 0x1c(%rcx), %eax
je 0x26df
movslq -0x9c(%rbp), %rax
movq -0x50(%rbp,%rax,8), %rsi
movq -0x80(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x1c(%rax), %edx
movslq -0x9c(%rbp), %rax
movl -0x70(%rbp,%rax,4), %ecx
leaq 0xaf1(%rip), %rdi       # 0x31bd
movb $0x0, %al
callq 0x1900
leaq 0x952(%rip), %rax       # 0x302c
movl (%rax), %eax
movl %eax, -0x8(%rbp)
jmp 0x26e1
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x2672
cmpl $0x0, -0x8(%rbp)
je 0x2708
leaq 0xae7(%rip), %rdi       # 0x31e6
movb $0x0, %al
callq 0x19c0
jmp 0x2716
leaq 0xaed(%rip), %rdi       # 0x31fc
movb $0x0, %al
callq 0x1900
xorl %eax, %eax
addq $0xa0, %rsp
popq %rbp
retq