// File: /workspace/github_c_makefile_star2_O3/salextpuru[P]speccy-toochain/src/mhmt/mhmt-parsearg.c
// Function: parse_args
ULONG parse_args(int argc, char* argv[])
{
    struct argtbl argstore[ARG_STORE_SIZE+1]; // last element is always stop-value
    struct argtbl * arg;
    ULONG inarg_pos; // position in argv[] array
    ULONG storearg_pos; // position in argstore[] array
    ULONG files_num; // number of filenames specified
    char * temp_filename;
    ULONG last_arg_type;
    ULONG maxwin;
    ULONG i;

    for(i=0; i<ARG_STORE_SIZE+1; i++) {
        argstore[i].name = NULL;
        argstore[i].type = ARG_NOARG;
    }

    if( argc<2 ) {
        printf("No arguments! Use \"mhmt -h\" or \"mhmt -help\" for help!\n");
        return 0L;
    }

    // shortcut for help request
    if( !cmp_str_nocase( argv[1]+1, "h" ) || !cmp_str_nocase( argv[1]+1, "help" ) )
        return ARG_PARSER_SHOWHELP;

    inarg_pos = 1;
    storearg_pos = 0;
    files_num = 0;

    // first find all arguments beginning with "-"
    while( inarg_pos<(ULONG)argc && *(argv[inarg_pos])=='-' ) {
        arg=match_arg(argv[inarg_pos]+1); // search match...

        if( arg ) { // match!
            if( storearg_pos>=ARG_STORE_SIZE ) {
                printf("Too many arguments!\n");
                return ARG_PARSER_ERROR|ARG_PARSER_SHOWHELP;
            }

            argstore[storearg_pos++] = *arg;

        } else { // argument does not match predefined set
            printf("Wrong arguments!\n");
            return ARG_PARSER_ERROR|ARG_PARSER_SHOWHELP;
        }

        inarg_pos++;
    }

    // parse filenames then
    while( inarg_pos<(ULONG)argc ) {
        if( files_num>=2 ) { // there should be no more than two filenames
            printf("Too many filenames specified!\n");
            return ARG_PARSER_ERROR|ARG_PARSER_SHOWHELP;
        }

        temp_filename = (char *)malloc( 1+strlen(argv[inarg_pos]) );

        if( !temp_filename ) {
            printf("Cannot allocate memory for filename string!\n");
            return ARG_PARSER_ERROR;
        }

        strcpy( temp_filename, argv[inarg_pos] );

        if( files_num==0 )
            wrk.fname_in = temp_filename;

        else // only files_num==1, because of condition in the beginning of current "while" cycle
            wrk.fname_out = temp_filename;

        files_num++;
        inarg_pos++;
    }

    if( !files_num ) { // there must be at least 1 filename specified
        printf("No filenames specified!\n");
        return ARG_PARSER_ERROR|ARG_PARSER_SHOWHELP;
    }

    // now optional arguments (starting with "-") are stored in argstore[],
    // all needed filenames are also copied, go proceed configuring with
    // optional arguments
    // sort argument array (in increasing .type order) to ensure correct parsing
    sort_args( argstore, ARG_STORE_SIZE );
    storearg_pos = 0;
    last_arg_type = ARG_INIT; // there is no such value in argstore[].type

    while( argstore[storearg_pos].type != ARG_NOARG ) {
        if( last_arg_type == argstore[storearg_pos].type ) {
            printf("Redundant arguments!\n");
            return ARG_PARSER_ERROR|ARG_PARSER_SHOWHELP;
        }

        switch( argstore[storearg_pos].type ) {
        case ARG_MODE:
            wrk.mode = 1; // set depack mode
            break;

        case ARG_GREEDY:
            if( wrk.mode ) { // since sorted, argument list causes parsing go from up to down in this "case" list
                printf("No greedy mode specification for DEpacking!\n");
                return ARG_PARSER_ERROR;
            }

            wrk.greedy = 1; // set greedy packing mode
            break;

        case ARG_PTYPE:
            if( !cmp_str_nocase( argstore[storearg_pos].name, ARGSTR_MEGALZ ) ) {
                wrk.packtype = PK_MLZ;
                wrk.zxheader = 0;
                wrk.wordbit  = 0;
                wrk.bigend   = 0;
                wrk.fullbits = 0;
                wrk.maxwin   = 4352;

            } else if( !cmp_str_nocase( argstore[storearg_pos].name, ARGSTR_HRUM ) ) {
                wrk.packtype = PK_HRM;
                wrk.zxheader = 0; // by default, there is NO ZX-HEADER if only -hrm or -hst specified
                wrk.wordbit  = 1;
                wrk.bigend   = 0;
                wrk.fullbits = 1;
                wrk.maxwin   = 4096;

            } else if( !cmp_str_nocase( argstore[storearg_pos].name, ARGSTR_HRUST ) ) {
                wrk.packtype = PK_HST;
                wrk.zxheader = 0; // by default, there is NO ZX-HEADER if only -hrm or -hst specified
                wrk.wordbit  = 1;
                wrk.bigend   = 0;
                wrk.fullbits = 1;
                wrk.maxwin   = 65536;

            } else { // there shouldn't be this case, but nevertheless...
                printf("Impossible error #1! Press any key to continue or \"SPACE\" to exit... :-)\n");
                return ARG_PARSER_ERROR;
            }

            break;

        case ARG_ZXHEAD:

            // ZX-header is not applicable for PK_MLZ type...
            // also wrk.packtype has been already set before...
            if( PK_MLZ==wrk.packtype ) {
                printf("There couldn't be zx-header in megalz mode!\n");
                return ARG_PARSER_ERROR;
            }

            wrk.zxheader = 1;
            break;

        case ARG_WORD:

            // whether bits must be grouped in words or in bytes
            if( !cmp_str_nocase( argstore[storearg_pos].name, ARGSTR_8 ) ) {
                if( wrk.zxheader ) { // won't force byte-wise bits when there is a zx-header
                    printf("There can be only 16bit grouping of bits when ZX-header is active!\n");
                    return ARG_PARSER_ERROR;
                }

                wrk.wordbit = 0;

            } else if( !cmp_str_nocase( argstore[storearg_pos].name, ARGSTR_16 ) ) {
                wrk.wordbit = 1;

            } else { // there shouldn't be this case, but nevertheless...
                printf("Impossible error #2! Press any key to continue or \"SPACE\" to exit... :-)\n");
                return ARG_PARSER_ERROR;
            }

            break;

        case ARG_BIGEND:

            // whether word-grouped bits must be big- or little-endian arranged
            if( wrk.zxheader ) {
                printf("There can be only little-endian arrangement of bits when ZX-header is active!\n");
                return ARG_PARSER_ERROR;
            }

            wrk.bigend = 1;
            break;

        case ARG_MAXWIN:
            maxwin = get_maxwin( argstore[storearg_pos].name );

            if( !maxwin ) { // there shouldn't be this case, but nevertheless...
                printf("Impossible error #3! Press any key to continue or \"SPACE\" to exit... :-)\n");
                return ARG_PARSER_ERROR;
            }

            // wrk.maxwin is already initialized to the maximum value suitable for given packing type, so check new setting
            if( maxwin > wrk.maxwin ) {
                printf("Maximum window specified is too big for given packing type!\n");
                return ARG_PARSER_ERROR;
            }

            wrk.maxwin = maxwin;
            break;

        default:
            // once again impossible error: we shouldn't be here since "while" loop condition...
            printf("Impossible error #4! Press any key to continue or \"SPACE\" to exit... :-)\n");
            return ARG_PARSER_ERROR;
            break;
        }

        last_arg_type = argstore[storearg_pos++].type;
    }

    return ARG_PARSER_GO;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movq %rsi, %r15
movl %edi, %r14d
movl $0x8, %eax
movq $0x0, 0x28(%rsp,%rax)
movl $0xff, 0x30(%rsp,%rax)
addq $0x10, %rax
cmpq $0x118, %rax            # imm = 0x118
jne 0x37ac
cmpl $0x2, %r14d
jge 0x37dd
xorl %ebp, %ebp
leaq 0x3b2b(%rip), %rdi      # 0x7303
jmp 0x38de
movq 0x8(%r15), %rbx
incq %rbx
leaq 0x37b5(%rip), %rsi      # 0x6fa0
movq %rbx, %rdi
callq 0x3ce7
movl $0x1, %ebp
testl %eax, %eax
je 0x38e3
leaq 0x3812(%rip), %rsi      # 0x7019
movq %rbx, %rdi
callq 0x3ce7
testl %eax, %eax
je 0x38e3
movq 0x6892(%rip), %rdi      # 0xa0b0
leal -0x1(%r14), %eax
movq %rax, 0x18(%rsp)
leaq 0x8(%r15), %rbx
movl $0x1, %ecx
xorl %r13d, %r13d
leaq 0x6886(%rip), %rax      # 0xa0c0
movq %rdi, 0x8(%rsp)
movq %rcx, 0x10(%rsp)
movq (%r15,%rcx,8), %r12
cmpb $0x2d, (%r12)
jne 0x38f7
movl $0x101, %ebp            # imm = 0x101
testq %rdi, %rdi
je 0x3c50
incq %r12
movq %rax, %rbp
movq %r12, %rsi
callq 0x3ce7
testl %eax, %eax
je 0x3882
movq (%rbp), %rdi
addq $0x10, %rbp
testq %rdi, %rdi
jne 0x3867
jmp 0x38d2
cmpq $0x10, %r13
je 0x3c5c
addq $-0x10, %rbp
leaq 0x1(%r13), %rax
shlq $0x4, %r13
movups (%rbp), %xmm0
movups %xmm0, 0x30(%rsp,%r13)
movq 0x10(%rsp), %rcx
incq %rcx
addq $0x8, %rbx
movq %rax, %r13
cmpq 0x18(%rsp), %rax
movq 0x8(%rsp), %rdi
leaq 0x67fe(%rip), %rax      # 0xa0c0
jne 0x383f
movl $0x101, %ebp            # imm = 0x101
jmp 0x3c44
leaq 0x3a05(%rip), %rdi      # 0x72de
movl $0x101, %ebp            # imm = 0x101
callq 0x1120
movl %ebp, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x101, %ebp            # imm = 0x101
movq 0x10(%rsp), %rax
cmpl %r14d, %eax
jae 0x3c44
movl %r14d, %ecx
negl %ecx
addq %rax, %rcx
movq %rcx, 0x8(%rsp)
xorl %r13d, %r13d
cmpl $0x2, %r13d
je 0x3c68
movq (%rbx), %r15
movq %r15, %rdi
callq 0x1050
leaq 0x1(%rax), %rdi
callq 0x10e0
testq %rax, %rax
je 0x3c74
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x1070
xorl %eax, %eax
testl %r13d, %r13d
setne %al
leaq 0x79c2(%rip), %rcx      # 0xb320
movq %r12, 0x20(%rcx,%rax,8)
addq $0x8, %rbx
incq %r13
movq 0x8(%rsp), %rax
addl %r13d, %eax
jne 0x391a
cmpl %r14d, 0x10(%rsp)
jae 0x3c44
movl $0xe, %eax
movl $0xf0, %ecx
xorl %edx, %edx
movl 0x38(%rsp,%rdx), %esi
cmpl 0x48(%rsp,%rdx), %esi
jbe 0x39b5
leaq (%rsp,%rdx), %rsi
addq $0x30, %rsi
movups (%rsi), %xmm0
movaps %xmm0, 0x20(%rsp)
movaps 0x10(%rsi), %xmm0
movaps %xmm0, (%rsi)
movaps 0x20(%rsp), %xmm0
movups %xmm0, 0x10(%rsi)
addq $0x10, %rdx
cmpq %rdx, %rcx
jne 0x398b
addq $-0x10, %rcx
subl $0x1, %eax
jae 0x3989
movl 0x38(%rsp), %ecx
movl $0x2, %ebp
cmpl $0xff, %ecx
je 0x38e3
leaq 0x793d(%rip), %rax      # 0xb320
movl (%rax), %edx
movl %edx, 0x18(%rsp)
movl 0x8(%rax), %edx
movl %edx, 0x10(%rsp)
movl 0xc(%rax), %ebx
movl 0x1c(%rax), %eax
movl %eax, 0x8(%rsp)
xorl %r12d, %r12d
leaq 0x30(%rsp), %rax
movl $0x1, %r14d
leaq 0x3571(%rip), %r15      # 0x6f80
movq %r15, %r13
cmpl %ecx, %r12d
je 0x3c85
movl %ecx, %r12d
leal -0x1(%r12), %ecx
cmpl $0x6, %ecx
ja 0x3c96
movslq (%r15,%rcx,4), %rcx
addq %r15, %rcx
jmpq *%rcx
leaq 0x78e4(%rip), %rax      # 0xb320
movl $0x1, 0x8(%rax)
movl $0x1, 0x10(%rsp)
jmp 0x3c1f
movq (%rax), %r15
movq %r15, %rdi
leaq 0x3575(%rip), %rsi      # 0x6fd2
callq 0x3ce7
testl %eax, %eax
je 0x3ba2
movq %r15, %rdi
leaq 0x352e(%rip), %rsi      # 0x6fa2
callq 0x3ce7
testl %eax, %eax
jne 0x3ccc
leaq 0x7898(%rip), %rax      # 0xb320
movl $0x1, 0x10(%rax)
jmp 0x3c1c
movq (%rax), %r15
movq %r15, %rdi
leaq 0x2b8a(%rip), %rsi      # 0x662b
callq 0x3ce7
testl %eax, %eax
je 0x3bbc
movq %r15, %rdi
leaq 0x2b78(%rip), %rsi      # 0x6630
callq 0x3ce7
testl %eax, %eax
je 0x3beb
movq %r15, %rdi
leaq 0x2b66(%rip), %rsi      # 0x6635
callq 0x3ce7
testl %eax, %eax
jne 0x3cd5
leaq 0x783d(%rip), %rax      # 0xb320
movl $0x3, (%rax)
movaps 0x3470(%rip), %xmm0     # 0x6f60
movups %xmm0, 0xc(%rax)
movl $0x10000, 0x1c(%rax)    # imm = 0x10000
movl $0x10000, 0x8(%rsp)     # imm = 0x10000
xorl %ebx, %ebx
movl $0x3, 0x18(%rsp)
jmp 0x3c1c
cmpl $0x1, 0x18(%rsp)
je 0x3cba
leaq 0x77fc(%rip), %rax      # 0xb320
movl $0x1, 0xc(%rax)
movl $0x1, %ebx
jmp 0x3c1f
cmpl $0x0, 0x10(%rsp)
jne 0x3ca8
leaq 0x77d9(%rip), %rax      # 0xb320
movl $0x1, 0x4(%rax)
movl $0x0, 0x10(%rsp)
jmp 0x3c1f
testl %ebx, %ebx
jne 0x3cb1
leaq 0x77b6(%rip), %rax      # 0xb320
movl $0x1, 0x14(%rax)
xorl %ebx, %ebx
jmp 0x3c1f
movq (%rax), %rdi
callq 0x3de4
testl %eax, %eax
je 0x3c9f
cmpl 0x8(%rsp), %eax
ja 0x3cc3
leaq 0x7787(%rip), %rcx      # 0xb320
movl %eax, 0x1c(%rcx)
movl %eax, 0x8(%rsp)
jmp 0x3c1f
testl %ebx, %ebx
jne 0x3cde
leaq 0x776f(%rip), %rax      # 0xb320
movl $0x0, 0x10(%rax)
xorl %ebx, %ebx
jmp 0x3c1c
leaq 0x775d(%rip), %rax      # 0xb320
movl $0x1, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movl $0x1100, 0x1c(%rax)     # imm = 0x1100
movl $0x1100, 0x8(%rsp)      # imm = 0x1100
xorl %ebx, %ebx
movl $0x1, 0x18(%rsp)
jmp 0x3c1c
leaq 0x772e(%rip), %rax      # 0xb320
movl $0x2, (%rax)
movaps 0x3361(%rip), %xmm0     # 0x6f60
movups %xmm0, 0xc(%rax)
movl $0x1000, 0x1c(%rax)     # imm = 0x1000
movl $0x1000, 0x8(%rsp)      # imm = 0x1000
xorl %ebx, %ebx
movl $0x2, 0x18(%rsp)
movq %r13, %r15
movl %r14d, %eax
shlq $0x4, %rax
addq %rsp, %rax
addq $0x30, %rax
movl 0x8(%rax), %ecx
incl %r14d
cmpl $0xff, %ecx
jne 0x3a12
jmp 0x38e3
leaq 0x33d3(%rip), %rdi      # 0x701e
jmp 0x38de
leaq 0x3687(%rip), %rdi      # 0x72de
jmp 0x38de
leaq 0x368c(%rip), %rdi      # 0x72ef
jmp 0x38d9
leaq 0x3651(%rip), %rdi      # 0x72c0
jmp 0x38de
leaq 0x3619(%rip), %rdi      # 0x7294
movl $0x100, %ebp            # imm = 0x100
jmp 0x38de
movl $0x101, %ebp            # imm = 0x101
leaq 0x35ee(%rip), %rdi      # 0x727f
jmp 0x38de
leaq 0x3599(%rip), %rdi      # 0x7236
jmp 0x3c7b
leaq 0x3390(%rip), %rdi      # 0x7036
jmp 0x3c7b
leaq 0x355b(%rip), %rdi      # 0x720a
jmp 0x3c7b
leaq 0x3403(%rip), %rdi      # 0x70bb
jmp 0x3c7b
leaq 0x34d4(%rip), %rdi      # 0x7195
jmp 0x3c7b
leaq 0x33b5(%rip), %rdi      # 0x707f
jmp 0x3c7b
leaq 0x3479(%rip), %rdi      # 0x714c
jmp 0x3c7b
leaq 0x34e5(%rip), %rdi      # 0x71c1
jmp 0x3c7b
leaq 0x3424(%rip), %rdi      # 0x7109
jmp 0x3c7b