// File: /workspace/github_cpp_makefile_star2_O2/JameyWoo[P]re2graph/main.cpp
// Function: main
int main(int argc, char *argv[]) {
    string rexp, strm, pngfile;  // * regular expression, string_to_match
    string pattern;              // * 状态图的布局模式
    string graphes;              // * 要画的图形

    // * 参数的解析
    if (argc == 1) {
        help();
        return 0;
    }

    int o;
    string optstring = "hir:s:o:p:g:";  // 可以有的选项, : 代表后面需要跟参数
    while ((o = getopt(argc, argv, optstring.c_str())) != -1) {
        switch (o) {
            case 'h':
                help();
                return 0;
            case '?':
                cout << "error optopt: " << char(optopt) << endl;
                help();
                return 0;
            case 'i':
                cout << "please input the re_expression:\n->$ ";
                cin >> rexp;
                cout << "please input the string to match:\n->$ ";
                cin >> strm;
                break;
            // r 和 s|o配合使用
            case 'r':
                rexp = optarg;
                cout << "re_expresion: " << rexp << endl;
                break;
            case 's':
                strm = optarg;
                cout << "string_to_match: " << strm << endl;
                break;
            case 'o':
                pngfile = optarg;
                cout << "png file: " << pngfile << endl;
                break;
            // 有o才有p
            case 'p':
                pattern = optarg;
                cout << "pattern: " << pattern << endl;
                break;
            case 'g':
                graphes = optarg;
                cout << "graphes: " << graphes << endl;
                break;
        }
    }

    // * 实现步骤, 保存了中间的nfa, dfa, mindfa 等文件在tmp文件夹中, 作为临时文件
    NFA mynfa = re2nfa(rexp);
    writeNfaData(mynfa, "./tmp/tmp.nfa");
    DFA mydfa;
    nfa2dfa(mynfa, mydfa);
    writeDfaData(mydfa, "./tmp/tmp.dfa");
    DFA my_min_dfa = dfa2min(mydfa);
    writeDfaData(my_min_dfa, "./tmp/tmp.mindfa");

    // * 根据输入的信息来执行程序
    if (strm.size()) {
        bool match = dfaPattern(my_min_dfa, strm);
        if (match) {
            cout << "\n*\nmatch succeeded!\n*\n"
                 << endl;
        } else {
            cout << "\n*\nmatch failed!\n*\n"
                 << endl;
        }
    }
    // 根据 pngfile 和 graphes 的选项画图. 如果不指定 graphes, 默认都画出来
    if (pngfile.size()) {
        string raw = pngfile;
        if ((count(graphes.begin(), graphes.end(), 'n') != 0) || graphes.size() == 0) {
            nfa2png(mynfa, pngfile.replace(pngfile.find(".png"), 4, "_nfa.png"), pattern);
            pngfile = raw;
        }
        if ((count(graphes.begin(), graphes.end(), 'm') != 0) || graphes.size() == 0) {
            dfa2png(my_min_dfa, pngfile.replace(pngfile.find(".png"), 4, "_mindfa.png"), pattern);
            pngfile = raw;
        }
        if ((count(graphes.begin(), graphes.end(), 'd') != 0) || graphes.size() == 0) {
            dfa2png(mydfa, pngfile.replace(pngfile.find(".png"), 4, "_dfa.png"), pattern);
            pngfile = raw;
        }
    }

    cout << "program over ... \n";
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x788, %rsp            # imm = 0x788
movq %rsi, %rbx
leaq 0x98(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
leaq 0xb8(%rsp), %rdx
movq %rdx, -0x10(%rdx)
andq $0x0, -0x8(%rdx)
leaq 0x38(%rsp), %rsi
movq %rsi, -0x10(%rsi)
andq $0x0, -0x8(%rsi)
movb %cl, (%rax)
movb %cl, (%rdx)
leaq 0x58(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq 0x18(%rsp), %rdx
movq %rdx, -0x10(%rdx)
andq $0x0, -0x8(%rdx)
movb %cl, (%rsi)
movb %cl, (%rax)
movb %cl, (%rdx)
cmpl $0x1, %edi
jne 0x25a7
callq 0x88dd
jmp 0x2d0c
movl %edi, %ebp
leaq 0xca88(%rip), %rsi      # 0xf038
leaq 0x228(%rsp), %rdi
leaq 0x328(%rsp), %rdx
callq 0x2f70
leaq 0xca38(%rip), %r12      # 0xf004
movq 0x149e5(%rip), %r13     # 0x16fb8
movq 0x149f6(%rip), %r15     # 0x16fd0
leaq 0xa8(%rsp), %r14
movq 0x228(%rsp), %rdx
movl %ebp, %edi
movq %rbx, %rsi
callq 0x2050
leal -0x67(%rax), %ecx
cmpl $0xc, %ecx
ja 0x271e
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movq (%r13), %rsi
leaq 0x8(%rsp), %rdi
callq 0x23a0
movq %r15, %rdi
leaq 0xcab5(%rip), %rsi      # 0xf0d6
callq 0x21f0
leaq 0x8(%rsp), %rsi
jmp 0x2709
movq (%r13), %rsi
leaq 0x48(%rsp), %rdi
callq 0x23a0
movq %r15, %rdi
leaq 0xca84(%rip), %rsi      # 0xf0cc
callq 0x21f0
leaq 0x48(%rsp), %rsi
jmp 0x2709
movq %r15, %rdi
leaq 0xc9f3(%rip), %rsi      # 0xf054
callq 0x21f0
movq 0x14973(%rip), %rdi     # 0x16fe0
leaq 0x88(%rsp), %rsi
callq 0x22b0
movq %r15, %rdi
leaq 0xc9f5(%rip), %rsi      # 0xf079
callq 0x21f0
movq 0x14950(%rip), %rdi     # 0x16fe0
movq %r14, %rsi
callq 0x22b0
jmp 0x25e2
movq (%r13), %rsi
movq %r14, %rdi
callq 0x23a0
movq %r15, %rdi
leaq 0xc9fc(%rip), %rsi      # 0xf0af
callq 0x21f0
movq %r14, %rsi
jmp 0x2709
movq (%r13), %rsi
leaq 0x28(%rsp), %rdi
callq 0x23a0
movq %r15, %rdi
leaq 0xc9ec(%rip), %rsi      # 0xf0c1
callq 0x21f0
leaq 0x28(%rsp), %rsi
jmp 0x2709
movq (%r13), %rsi
leaq 0x88(%rsp), %rdi
callq 0x23a0
movq %r15, %rdi
leaq 0xc9a4(%rip), %rsi      # 0xf0a0
callq 0x21f0
leaq 0x88(%rsp), %rsi
movq %rax, %rdi
callq 0x21e0
movq %rax, %rdi
callq 0x20f0
jmp 0x25e2
cmpl $-0x1, %eax
je 0x2763
cmpl $0x3f, %eax
jne 0x25e2
movq 0x1489d(%rip), %rdi     # 0x16fd0
leaq 0xc90b(%rip), %rsi      # 0xf045
callq 0x21f0
movq 0x14882(%rip), %rcx     # 0x16fc8
movsbl (%rcx), %esi
movq %rax, %rdi
callq 0x2270
movq %rax, %rdi
callq 0x20f0
callq 0x88dd
jmp 0x2cff
leaq 0x208(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x22d0
leaq 0x328(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x3bf4
leaq 0x208(%rsp), %rdi
callq 0x20d0
leaq 0x718(%rsp), %rdi
leaq 0x328(%rsp), %rsi
callq 0x2fac
leaq 0xc92a(%rip), %rsi      # 0xf0e0
leaq 0x1e8(%rsp), %rdi
leaq 0x248(%rsp), %rdx
callq 0x2f70
leaq 0x718(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0x7c21
leaq 0x1e8(%rsp), %rdi
callq 0x20d0
leaq 0x718(%rsp), %rdi
callq 0x303e
xorps %xmm0, %xmm0
movups %xmm0, 0x2a8(%rsp)
movups %xmm0, 0x298(%rsp)
movups %xmm0, 0x288(%rsp)
movups %xmm0, 0x278(%rsp)
movups %xmm0, 0x268(%rsp)
movups %xmm0, 0x258(%rsp)
leaq 0x6a8(%rsp), %rdi
leaq 0x328(%rsp), %rsi
callq 0x2fac
leaq 0x6a8(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x4ce3
leaq 0x6a8(%rsp), %rdi
callq 0x303e
leaq 0x638(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x306a
leaq 0xc86e(%rip), %rsi      # 0xf0ee
leaq 0x1c8(%rsp), %rdi
leaq 0x2b8(%rsp), %rdx
callq 0x2f70
leaq 0x638(%rsp), %rdi
leaq 0x1c8(%rsp), %rsi
callq 0x84a0
leaq 0x1c8(%rsp), %rdi
callq 0x20d0
leaq 0x638(%rsp), %rdi
callq 0x30fc
leaq 0x5c8(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x306a
leaq 0x2b8(%rsp), %rdi
leaq 0x5c8(%rsp), %rsi
callq 0x59ee
leaq 0x5c8(%rsp), %rdi
callq 0x30fc
leaq 0x558(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x306a
leaq 0xc7e5(%rip), %rsi      # 0xf0fc
leaq 0x1a8(%rsp), %rdi
leaq 0x68(%rsp), %rdx
callq 0x2f70
leaq 0x558(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x84a0
leaq 0x1a8(%rsp), %rdi
callq 0x20d0
leaq 0x558(%rsp), %rdi
callq 0x30fc
cmpq $0x0, 0xb0(%rsp)
je 0x29ea
leaq 0x4e8(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x306a
leaq 0x188(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x22d0
leaq 0x4e8(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x6366
movl %eax, %ebx
leaq 0x188(%rsp), %rdi
callq 0x20d0
leaq 0x4e8(%rsp), %rdi
callq 0x30fc
leaq 0xc744(%rip), %rax      # 0xf10d
leaq 0xc754(%rip), %rsi      # 0xf124
testb %bl, %bl
cmovneq %rax, %rsi
movq 0x145f3(%rip), %rdi     # 0x16fd0
callq 0x21f0
movq %rax, %rdi
callq 0x20f0
cmpq $0x0, 0x30(%rsp)
je 0x2cc5
leaq 0x68(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x22d0
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
addq %rdi, %rsi
leaq 0x7(%rsp), %rdx
movb $0x6e, (%rdx)
callq 0x3bd7
testq %rax, %rax
je 0x2ae4
leaq 0x478(%rsp), %rdi
leaq 0x328(%rsp), %rsi
callq 0x2fac
leaq 0xc70d(%rip), %rsi      # 0xf151
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x23c0
leaq 0xc6de(%rip), %rcx      # 0xf138
pushq $0x4
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2130
leaq 0x168(%rsp), %rdi
movq %rax, %rsi
callq 0x22d0
leaq 0x148(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x22d0
leaq 0x478(%rsp), %rdi
leaq 0x168(%rsp), %rsi
leaq 0x148(%rsp), %rdx
callq 0x6472
leaq 0x148(%rsp), %rdi
callq 0x20d0
leaq 0x168(%rsp), %rdi
callq 0x20d0
leaq 0x478(%rsp), %rdi
callq 0x303e
leaq 0x28(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x2110
movq 0x10(%rsp), %rsi
jmp 0x2af2
movq 0x10(%rsp), %rsi
testq %rsi, %rsi
je 0x2a28
movq 0x8(%rsp), %rdi
addq %rdi, %rsi
leaq 0x7(%rsp), %rdx
movb $0x6d, (%rdx)
callq 0x3bd7
testq %rax, %rax
je 0x2bcc
leaq 0x408(%rsp), %rdi
leaq 0x2b8(%rsp), %rsi
callq 0x306a
leaq 0xc625(%rip), %rsi      # 0xf151
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x23c0
leaq 0xc5ff(%rip), %rcx      # 0xf141
pushq $0x4
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2130
leaq 0x128(%rsp), %rdi
movq %rax, %rsi
callq 0x22d0
leaq 0x108(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x22d0
leaq 0x408(%rsp), %rdi
leaq 0x128(%rsp), %rsi
leaq 0x108(%rsp), %rdx
callq 0x6e1b
leaq 0x108(%rsp), %rdi
callq 0x20d0
leaq 0x128(%rsp), %rdi
callq 0x20d0
leaq 0x408(%rsp), %rdi
callq 0x30fc
leaq 0x28(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x2110
movq 0x10(%rsp), %rsi
jmp 0x2bda
movq 0x10(%rsp), %rsi
testq %rsi, %rsi
je 0x2b10
movq 0x8(%rsp), %rdi
addq %rdi, %rsi
leaq 0x7(%rsp), %rdx
movb $0x64, (%rdx)
callq 0x3bd7
testq %rax, %rax
je 0x2caf
leaq 0x398(%rsp), %rdi
leaq 0x248(%rsp), %rsi
callq 0x306a
leaq 0xc53d(%rip), %rsi      # 0xf151
leaq 0x28(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0x23c0
leaq 0xc523(%rip), %rcx      # 0xf14d
pushq $0x4
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2130
leaq 0xe8(%rsp), %rdi
movq %rax, %rsi
callq 0x22d0
leaq 0xc8(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x22d0
leaq 0x398(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
leaq 0xc8(%rsp), %rdx
callq 0x6e1b
leaq 0xc8(%rsp), %rdi
callq 0x20d0
leaq 0xe8(%rsp), %rdi
callq 0x20d0
leaq 0x398(%rsp), %rdi
callq 0x30fc
leaq 0x28(%rsp), %rdi
leaq 0x68(%rsp), %rsi
callq 0x2110
jmp 0x2cbb
cmpq $0x0, 0x10(%rsp)
je 0x2bf8
leaq 0x68(%rsp), %rdi
callq 0x20d0
movq 0x14304(%rip), %rdi     # 0x16fd0
leaq 0xc483(%rip), %rsi      # 0xf156
callq 0x21f0
leaq 0x2b8(%rsp), %rdi
callq 0x30fc
leaq 0x248(%rsp), %rdi
callq 0x30fc
leaq 0x328(%rsp), %rdi
callq 0x303e
leaq 0x228(%rsp), %rdi
callq 0x20d0
leaq 0x8(%rsp), %rdi
callq 0x20d0
leaq 0x48(%rsp), %rdi
callq 0x20d0
leaq 0x28(%rsp), %rdi
callq 0x20d0
leaq 0xa8(%rsp), %rdi
callq 0x20d0
leaq 0x88(%rsp), %rdi
callq 0x20d0
xorl %eax, %eax
addq $0x788, %rsp            # imm = 0x788
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x20d0
jmp 0x2d6d
movq %rax, %rbx
leaq 0xe8(%rsp), %rdi
callq 0x20d0
jmp 0x2dfa
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x20d0
jmp 0x2d91
movq %rax, %rbx
leaq 0x128(%rsp), %rdi
callq 0x20d0
jmp 0x2e07
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x20d0
jmp 0x2db5
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x20d0
jmp 0x2e1c
jmp 0x2ee1
jmp 0x2ee1
jmp 0x2ee1
jmp 0x2ed7
movq %rax, %rbx
leaq 0x188(%rsp), %rdi
callq 0x20d0
jmp 0x2ded
movq %rax, %rbx
leaq 0x4e8(%rsp), %rdi
jmp 0x2e4b
movq %rax, %rbx
leaq 0x398(%rsp), %rdi
jmp 0x2e0f
movq %rax, %rbx
leaq 0x408(%rsp), %rdi
callq 0x30fc
jmp 0x2ee4
movq %rax, %rbx
leaq 0x478(%rsp), %rdi
callq 0x303e
jmp 0x2ee4
movq %rax, %rbx
leaq 0x1a8(%rsp), %rdi
callq 0x20d0
jmp 0x2e43
movq %rax, %rbx
leaq 0x558(%rsp), %rdi
callq 0x30fc
jmp 0x2eee
movq %rax, %rbx
leaq 0x5c8(%rsp), %rdi
jmp 0x2ef6
jmp 0x2edc
movq %rax, %rbx
leaq 0x1c8(%rsp), %rdi
callq 0x20d0
jmp 0x2e7c
movq %rax, %rbx
leaq 0x638(%rsp), %rdi
jmp 0x2ef6
movq %rax, %rbx
leaq 0x6a8(%rsp), %rdi
callq 0x303e
jmp 0x2efb
movq %rax, %rbx
leaq 0x1e8(%rsp), %rdi
callq 0x20d0
jmp 0x2ead
movq %rax, %rbx
leaq 0x718(%rsp), %rdi
callq 0x303e
jmp 0x2f08
movq %rax, %rbx
jmp 0x2f08
movq %rax, %rbx
leaq 0x208(%rsp), %rdi
callq 0x20d0
jmp 0x2f23
jmp 0x2f20
jmp 0x2ed7
movq %rax, %rbx
jmp 0x2eee
movq %rax, %rbx
jmp 0x2efb
movq %rax, %rbx
leaq 0x68(%rsp), %rdi
callq 0x20d0
leaq 0x2b8(%rsp), %rdi
callq 0x30fc
leaq 0x248(%rsp), %rdi
callq 0x30fc
leaq 0x328(%rsp), %rdi
callq 0x303e
jmp 0x2f23
jmp 0x2f19
movq %rax, %rbx
jmp 0x2f30
jmp 0x2f20
movq %rax, %rbx
leaq 0x228(%rsp), %rdi
callq 0x20d0
leaq 0x8(%rsp), %rdi
callq 0x20d0
leaq 0x48(%rsp), %rdi
callq 0x20d0
leaq 0x28(%rsp), %rdi
callq 0x20d0
leaq 0xa8(%rsp), %rdi
callq 0x20d0
leaq 0x88(%rsp), %rdi
callq 0x20d0
movq %rbx, %rdi
callq 0x2370