// File: /workspace/github_c_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0x1468(%rip), %rax      # 0x3044
movl (%rax), %eax
movl %eax, (%rsp)
leaq -0x474(%rip), %rsi      # 0x1774
movl $0x100000, %edi         # imm = 0x100000
callq 0x177f
movl $0x38, %edi
callq 0x19b8
movq %rax, %rbx
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x1269
movq %rax, %r14
leaq 0x319d(%rip), %r15      # 0x4db0
movq (%r12,%r15), %rsi
movq %r14, %rdi
callq 0x131b
movq %rax, (%rbx,%r12)
addq $0x8, %r12
cmpq $0x38, %r12
jne 0x1c13
movq %r14, %rdi
callq 0x1403
movq (%r14), %rdx
movq 0x8(%rdx), %rcx
cmpq %rdx, %rcx
je 0x1c65
leaq 0x154d(%rip), %rdi      # 0x3195
movq %rdx, %rsi
xorl %eax, %eax
callq 0x10a0
leaq 0x13ef(%rip), %rax      # 0x3048
movl (%rax), %r12d
movq (%r14), %rdx
movl (%rsp), %r13d
jmp 0x1c6c
movl (%rsp), %r13d
movl %r13d, %r12d
movq (%rdx), %rdi
movq 0x308(%rdi), %rsi
movq 0x8(%rsi), %rcx
cmpq %rdx, %rcx
je 0x1ca5
leaq 0x150f(%rip), %rdi      # 0x3195
xorl %eax, %eax
callq 0x10a0
leaq 0x13b4(%rip), %rax      # 0x3048
movl (%rax), %ebp
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x308(%rdi), %rsi
jmp 0x1ca8
movl %r13d, %ebp
movq (%rsi), %rax
movq 0x310(%rax), %rsi
movq 0x310(%rdi), %rax
movq 0x8(%rsi), %rcx
cmpq %rax, %rcx
je 0x1cea
leaq 0x14cc(%rip), %rdi      # 0x3195
movq %rax, %rdx
xorl %eax, %eax
callq 0x10a0
leaq 0x136e(%rip), %rax      # 0x3048
movl (%rax), %r13d
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x310(%rdi), %rax
andl %ebp, %r12d
movq 0x8(%rax), %rcx
cmpq %rdx, %rcx
je 0x1d20
leaq 0x1498(%rip), %rdi      # 0x3195
movq %rax, %rsi
xorl %eax, %eax
callq 0x10a0
leaq 0x133a(%rip), %rax      # 0x3048
movl (%rax), %r9d
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x310(%rdi), %rax
jmp 0x1d24
movl (%rsp), %r9d
andl %r13d, %r12d
movq (%rax), %r8
movq 0x308(%r8), %rsi
movq 0x308(%rdi), %rax
movq 0x8(%rsi), %rcx
cmpq %rax, %rcx
je 0x1d85
leaq 0x144d(%rip), %rdi      # 0x3195
movq %rax, %rdx
xorl %eax, %eax
movl %r9d, %ebp
callq 0x10a0
movl %ebp, %r9d
leaq 0x12e9(%rip), %rax      # 0x3048
movl (%rax), %ebp
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x308(%rdi), %rax
movq 0x310(%rdi), %rcx
movq (%rcx), %r8
movq 0x308(%r8), %rsi
movl (%rsp), %r13d
jmp 0x1d8c
movl (%rsp), %r13d
movl %r13d, %ebp
andl %r9d, %r12d
movq (%rsi), %rcx
movq 0x310(%rcx), %rsi
movq (%rax), %rax
movq 0x310(%rax), %rax
movq 0x8(%rsi), %rcx
cmpq %rax, %rcx
je 0x1dd7
leaq 0x13e2(%rip), %rdi      # 0x3195
movq %rax, %rdx
xorl %eax, %eax
callq 0x10a0
leaq 0x1284(%rip), %rax      # 0x3048
movl (%rax), %r13d
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x310(%rdi), %rax
movq (%rax), %r8
andl %ebp, %r12d
movq 0x318(%r8), %rsi
movq 0x318(%rdi), %rax
movq 0x8(%rsi), %rcx
cmpq %rax, %rcx
je 0x1e2f
leaq 0x139d(%rip), %rdi      # 0x3195
movq %rax, %rdx
xorl %eax, %eax
callq 0x10a0
leaq 0x123f(%rip), %rax      # 0x3048
movl (%rax), %ebp
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x310(%rdi), %rcx
movq 0x318(%rdi), %rax
movq (%rcx), %rcx
movq 0x318(%rcx), %rsi
movl (%rsp), %r9d
jmp 0x1e36
movl (%rsp), %r9d
movl %r9d, %ebp
andl %r13d, %r12d
movq (%rsi), %rcx
movq 0x308(%rcx), %rsi
movq (%rax), %rcx
movq 0x308(%rcx), %r8
movq 0x8(%rsi), %rcx
movl %r9d, %r13d
cmpq %r8, %rcx
je 0x1e81
leaq 0x1335(%rip), %rdi      # 0x3195
movq %r8, %rdx
xorl %eax, %eax
callq 0x10a0
leaq 0x11d7(%rip), %rax      # 0x3048
movl (%rax), %r13d
movq (%r14), %rdx
movq (%rdx), %rdi
movq 0x318(%rdi), %rax
andl %ebp, %r12d
movq 0x8(%rax), %rcx
cmpq %rdx, %rcx
je 0x1eb6
leaq 0x1301(%rip), %rdi      # 0x3195
movq %rax, %rsi
xorl %eax, %eax
callq 0x10a0
leaq 0x11a3(%rip), %rax      # 0x3048
movl (%rax), %ebp
movq (%r14), %rax
movq (%rax), %rdi
movq 0x318(%rdi), %rax
jmp 0x1eb9
movl (%rsp), %ebp
andl %r13d, %r12d
movq (%rax), %rax
movq 0x308(%rax), %rsi
movq 0x308(%rdi), %rdx
movq 0x8(%rsi), %rcx
cmpq %rdx, %rcx
je 0x1f11
leaq 0x12b8(%rip), %rdi      # 0x3195
xorl %eax, %eax
callq 0x10a0
leaq 0x115d(%rip), %rax      # 0x3048
movl (%rax), %r13d
movq (%r14), %rax
movq (%rax), %rax
movq 0x308(%rax), %rdx
movq 0x318(%rax), %rax
movq (%rax), %rax
movq 0x308(%rax), %rsi
movl (%rsp), %edi
jmp 0x1f17
movl (%rsp), %edi
movl %edi, %r13d
andl %ebp, %r12d
movq (%rsi), %rax
movq 0x308(%rax), %rsi
movq 0x8(%rsi), %rcx
movl %edi, %ebp
cmpq %rdx, %rcx
je 0x1f46
leaq 0x125f(%rip), %rdi      # 0x3195
xorl %eax, %eax
callq 0x10a0
leaq 0x1104(%rip), %rax      # 0x3048
movl (%rax), %ebp
andl %r13d, %r12d
movl %r12d, 0x4(%rsp)
movb $0x61, %al
movl $0x1, %r12d
leaq 0x1261(%rip), %r13      # 0x31be
movsbl %al, %esi
movq %r14, %rdi
callq 0x14c2
movb (%r12,%r13), %al
incq %r12
cmpq $0x10, %r12
jne 0x1f5d
movl 0x4(%rsp), %esi
andl %ebp, %esi
andl (%rsp), %esi
leaq 0x10c3(%rip), %rax      # 0x3048
movl (%rax), %ebp
leaq 0x12a2(%rip), %r13      # 0x3230
leaq 0x1248(%rip), %r14      # 0x31dd
xorl %r12d, %r12d
movl (%r12,%r13), %ecx
movq (%rbx,%r12,2), %rax
movl 0x1c(%rax), %edx
cmpl %edx, %ecx
je 0x1fb6
movq (%r15), %rsi
movq %r14, %rdi
xorl %eax, %eax
callq 0x10a0
movl %ebp, %esi
addq $0x8, %r15
addq $0x4, %r12
cmpq $0x1c, %r12
jne 0x1f98
testl %esi, %esi
je 0x1fd8
leaq 0x1237(%rip), %rdi      # 0x3206
xorl %eax, %eax
callq 0x1651
jmp 0x1fe6
leaq 0x123d(%rip), %rdi      # 0x321c
xorl %eax, %eax
callq 0x10a0
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq