// File: /workspace/github_c_makefile_star2_O0/ryvnf[P]czc/main.c
// Function: main
int main(int argc, char **argv)
{
    char *out = NULL;

    struct arg_list *gcc_args = arg_list_new("gcc");
    struct arg_list **gcc_args_tailp = &gcc_args->next;
    struct arg_list *src_files = NULL;
    struct arg_list **src_files_tailp = &src_files;

    // Colors are disabled to make messages from 'gcc' consistent with other
    // messages which doesn't have color.
    *gcc_args_tailp = arg_list_new("-fno-diagnostics-color");
    gcc_args_tailp = &(*gcc_args_tailp)->next;

    // We don't want warnings from GCC to leak through.  Will still output
    // errors if the generated code does not compile.
    *gcc_args_tailp = arg_list_new("-w");
    gcc_args_tailp = &(*gcc_args_tailp)->next;

    // Tell GCC that the source has been preprocessed.  This is to avoid having
    // to escape trigraphs in the generated C code.
    *gcc_args_tailp = arg_list_new("-fpreprocessed");
    gcc_args_tailp = &(*gcc_args_tailp)->next;

    int input_file_count = 0;

    enum {
        TO_EXE,
        TO_C,
        TO_ASM,
        TO_OBJ,
        AST_PRINT
    } mode = TO_EXE;

    for (int i = 1; i < argc; ++i) {
        if (argv[i][0] == '-') {
            if (strcmp(argv[i], "--print-ast") == 0) {
                mode = AST_PRINT;
                continue;
            }
            if (strcmp(argv[i], "--to-c") == 0) {
                mode = TO_C;
                *gcc_args_tailp = arg_list_new(argv[i]);
                gcc_args_tailp = &(*gcc_args_tailp)->next;
                continue;
            }

            switch (argv[i][1]) {
                // These options require thir arguments to be in the option
                // flag.  Their arguments can be anything.  They are copied
                // directly to the GCC command-line.
                case 'O':
                case 'f':
                    *gcc_args_tailp = arg_list_new(argv[i]);
                    gcc_args_tailp = &(*gcc_args_tailp)->next;
                    break;

                // The '-o' option doesn't require its arguments to be in the
                // option flag.  So if the flag doesn't have an argument, parse
                // the next argv element as argument for the option.  The
                // option gets added to the GCC command-line, but it also sets
                // the variable 'out'.
                case 'o':
                    *gcc_args_tailp = arg_list_new(argv[i]);
                    gcc_args_tailp = &(*gcc_args_tailp)->next;

                    if (argv[i][2] != '\0') {
                        out = argv[i] + 1;
                    } else {
                        if ((out = argv[++i]) == NULL)
                            missing_arg_for_opt(argv[i - 1]);
                        *gcc_args_tailp = arg_list_new(argv[i]);
                        gcc_args_tailp = &(*gcc_args_tailp)->next;
                    }

                    break;

                // These options doesn't require their arguments to be in the
                // option flag.  So if the flag doesn't have an argument, parse
                // the next argv element as argument for the option.  The
                // options are copied directly to the GCC command-line.
                case 'l':
                case 'L':
                    *gcc_args_tailp = arg_list_new(argv[i]);
                    gcc_args_tailp = &(*gcc_args_tailp)->next;

                    if (argv[i][2] == '\0') {
                        if (argv[++i] == NULL)
                            missing_arg_for_opt(argv[i - 1]);
                        *gcc_args_tailp = arg_list_new(argv[i]);
                        gcc_args_tailp = &(*gcc_args_tailp)->next;
                    }
                    break;

                case 'c':
                    mode = TO_OBJ;
                    if (argv[i][2] != '\0')
                        unrecognized_opt(argv[i]);

                    *gcc_args_tailp = arg_list_new(argv[i]);
                    gcc_args_tailp = &(*gcc_args_tailp)->next;
                    break;

                case 'S':
                    mode = TO_ASM;
                    if (argv[i][2] != '\0')
                        unrecognized_opt(argv[i]);

                    *gcc_args_tailp = arg_list_new(argv[i]);
                    gcc_args_tailp = &(*gcc_args_tailp)->next;
                    break;

                default:
                    unrecognized_opt(argv[i]);
            }
            continue;
        }

        // Arguments left are input files.  These are interpreted differently
        // depending on their extension, like .o for object files passed to the
        // linker or .s for assembly files passed to the assembler.  Only .z
        // and .zc files are recognized as source files for the language, all
        // other file types are passed directly to the GCC command-line.
        const char *ext = get_file_ext(argv[i]);
        input_file_count++;

        if (ext == NULL || (strcmp(ext, "z") != 0 &&
                    strcmp(ext, "zc") != 0 && strcmp(ext, "Z") != 0 &&
                    strcmp(ext, "ZC") != 0)) {
            *gcc_args_tailp = arg_list_new(argv[i]);
            gcc_args_tailp = &(*gcc_args_tailp)->next;
            continue;
        }

        *src_files_tailp = arg_list_new(argv[i]);
        src_files_tailp = &(*src_files_tailp)->next;
    }

    if (input_file_count == 0) {
        fatal(NULL, "no input files");
        exit(1);
    }


    if (out != NULL && input_file_count != 1 && mode != TO_EXE) {
        fatal(NULL, "cannot specify '-o' with '-c', '-S', or '-C' with "
                "multiple files\n");
        exit(1);
    }

    if (src_files != NULL) {
        if (mode == TO_C) {
            gen_c(src_files, out);
        } else if (mode == AST_PRINT) {
            print_ast_files(src_files);
        } else {
            invoke_gcc(src_files, gcc_args, gcc_args_tailp);
        }
    } else {
        invoke_gcc(src_files, gcc_args, gcc_args_tailp);
    }

    arg_list_del(src_files);
    arg_list_del(gcc_args);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
leaq 0x79b0(%rip), %rdi      # 0x13f55
callq 0xc0a0
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
leaq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
leaq 0x798f(%rip), %rdi      # 0x13f60
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
leaq 0x7981(%rip), %rdi      # 0x13f77
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
leaq 0x795f(%rip), %rdi      # 0x13f7a
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0xca4b
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0xc96e
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x7904(%rip), %rsi      # 0x13f89
callq 0x2110
cmpl $0x0, %eax
jne 0xc69b
movl $0x4, -0x40(%rbp)
jmp 0xca3d
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x78e7(%rip), %rsi      # 0x13f95
callq 0x2110
cmpl $0x0, %eax
jne 0xc6ee
movl $0x1, -0x40(%rbp)
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xca3d
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
addl $-0x4c, %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0x23, %eax
ja 0xc958
movq -0x58(%rbp), %rax
leaq 0x7735(%rip), %rcx      # 0x13e50
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xc969
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x2(%rax), %eax
cmpl $0x0, %eax
je 0xc7a8
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0xc806
movq -0x10(%rbp), %rax
movl -0x44(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x44(%rbp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, %rax
jne 0xc7dc
movq -0x10(%rbp), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
callq 0xbfe0
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xc969
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x2(%rax), %eax
cmpl $0x0, %eax
jne 0xc8a1
movq -0x10(%rbp), %rax
movl -0x44(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x44(%rbp)
movslq %ecx, %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0xc877
movq -0x10(%rbp), %rax
movl -0x44(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
callq 0xbfe0
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xc969
movl $0x3, -0x40(%rbp)
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x2(%rax), %eax
cmpl $0x0, %eax
je 0xc8d3
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xbfb0
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xc969
movl $0x2, -0x40(%rbp)
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x2(%rax), %eax
cmpl $0x0, %eax
je 0xc92c
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xbfb0
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xc969
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xbfb0
jmp 0xca3d
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc010
movq %rax, -0x50(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0xc9e7
movq -0x50(%rbp), %rdi
leaq 0x75fe(%rip), %rsi      # 0x13f9c
callq 0x2110
cmpl $0x0, %eax
je 0xca13
movq -0x50(%rbp), %rdi
leaq 0x75eb(%rip), %rsi      # 0x13f9e
callq 0x2110
cmpl $0x0, %eax
je 0xca13
movq -0x50(%rbp), %rdi
leaq 0x75d9(%rip), %rsi      # 0x13fa1
callq 0x2110
cmpl $0x0, %eax
je 0xca13
movq -0x50(%rbp), %rdi
leaq 0x75c6(%rip), %rsi      # 0x13fa3
callq 0x2110
cmpl $0x0, %eax
je 0xca13
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
jmp 0xca3d
movq -0x10(%rbp), %rax
movslq -0x44(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xc0a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rax
addq $0x8, %rax
movq %rax, -0x38(%rbp)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0xc64e
cmpl $0x0, -0x3c(%rbp)
jne 0xca63
xorl %eax, %eax
movl %eax, %edi
leaq 0x754a(%rip), %rsi      # 0x13fa6
movb $0x0, %al
callq 0x6610
cmpq $0x0, -0x18(%rbp)
je 0xca88
cmpl $0x1, -0x3c(%rbp)
je 0xca88
cmpl $0x0, -0x40(%rbp)
je 0xca88
xorl %eax, %eax
movl %eax, %edi
leaq 0x7534(%rip), %rsi      # 0x13fb5
movb $0x0, %al
callq 0x6610
cmpq $0x0, -0x30(%rbp)
je 0xcaca
cmpl $0x1, -0x40(%rbp)
jne 0xcaa4
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xc120
jmp 0xcac8
cmpl $0x4, -0x40(%rbp)
jne 0xcab5
movq -0x30(%rbp), %rdi
callq 0xc230
jmp 0xcac6
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xc290
jmp 0xcac8
jmp 0xcadb
movq -0x30(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xc290
movq -0x30(%rbp), %rdi
callq 0xc060
movq -0x20(%rbp), %rdi
callq 0xc060
movl -0x4(%rbp), %eax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)