// File: /workspace/github_c_makefile_star2_O1/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 0x37cc
cmpl $0x2, %r14d
jge 0x3806
xorl %r12d, %r12d
leaq 0x3b0a(%rip), %r13      # 0x7303
movq %r13, %rdi
callq 0x1120
jmp 0x3c22
movq 0x8(%r15), %rbx
incq %rbx
leaq 0x378c(%rip), %rsi      # 0x6fa0
movq %rbx, %rdi
callq 0x3cd5
movl $0x1, %r12d
testl %eax, %eax
je 0x3c22
leaq 0x37e8(%rip), %rsi      # 0x7019
movq %rbx, %rdi
callq 0x3cd5
testl %eax, %eax
je 0x3c22
movq 0x6868(%rip), %rbx      # 0xa0b0
movq %r14, 0x8(%rsp)
leal -0x1(%r14), %eax
movq %rax, 0x10(%rsp)
movl $0x1, %r14d
xorl %ebp, %ebp
movq (%r15,%r14,8), %r12
cmpb $0x2d, (%r12)
jne 0x38d9
testq %rbx, %rbx
je 0x3894
incq %r12
movq %rbx, %rdi
leaq 0x6835(%rip), %r13      # 0xa0b0
movq %r12, %rsi
callq 0x3cd5
testl %eax, %eax
je 0x3897
movq 0x10(%r13), %rdi
addq $0x10, %r13
testq %rdi, %rdi
jne 0x387b
xorl %r13d, %r13d
movl $0x101, %r12d           # imm = 0x101
testq %r13, %r13
je 0x3c37
cmpq $0x10, %rbp
je 0x3c43
leaq 0x1(%rbp), %rax
shlq $0x4, %rbp
movups (%r13), %xmm0
movups %xmm0, 0x30(%rsp,%rbp)
incq %r14
movq %rax, %rbp
cmpq 0x10(%rsp), %rax
jne 0x385e
movq 0x8(%rsp), %rbx
movl %ebx, %r14d
jmp 0x38de
movq 0x8(%rsp), %rbx
movl $0x101, %r12d           # imm = 0x101
leaq 0x3733(%rip), %r13      # 0x701e
subl %r14d, %ebx
jbe 0x37f9
movl %r14d, %eax
leaq (%r15,%rax,8), %r13
xorl %ebp, %ebp
cmpl $0x2, %ebp
je 0x3c4f
movq (%r13,%rbp,8), %r15
movq %r15, %rdi
callq 0x1050
leaq 0x1(%rax), %rdi
callq 0x10e0
testq %rax, %rax
je 0x3c5b
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x1070
xorl %eax, %eax
testl %ebp, %ebp
setne %al
leaq 0x79df(%rip), %rcx      # 0xb320
movq %r12, 0x20(%rcx,%rax,8)
incq %rbp
cmpl %ebp, %ebx
movl $0x101, %r12d           # imm = 0x101
jne 0x38fd
cmpl %r14d, 0x8(%rsp)
jbe 0x3c6d
movl $0xe, %eax
movl $0xf0, %ecx
xorl %edx, %edx
movl 0x38(%rsp,%rdx), %esi
cmpl 0x48(%rsp,%rdx), %esi
jbe 0x3994
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 0x396a
addq $-0x10, %rcx
subl $0x1, %eax
jae 0x3968
movl 0x38(%rsp), %ecx
movl $0x2, %r12d
cmpl $0xff, %ecx
je 0x3c22
leaq 0x795d(%rip), %rax      # 0xb320
movl (%rax), %edx
movl %edx, 0x8(%rsp)
movl 0x8(%rax), %ebx
movl 0xc(%rax), %ebp
movl 0x1c(%rax), %eax
movl %eax, 0x10(%rsp)
xorl %r15d, %r15d
leaq 0x30(%rsp), %rax
movl $0x1, %r14d
leaq 0x3894(%rip), %r13      # 0x727f
leaq 0x358e(%rip), %rsi      # 0x6f80
cmpl %ecx, %r15d
je 0x3c79
movl %ecx, %r15d
leal -0x1(%r15), %ecx
cmpl $0x6, %ecx
ja 0x3c84
movslq (%rsi,%rcx,4), %rcx
addq %rsi, %rcx
jmpq *%rcx
leaq 0x7905(%rip), %rax      # 0xb320
movl $0x1, 0x8(%rax)
movl $0x1, %ebx
jmp 0x3c02
movl %ebx, 0x1c(%rsp)
movq (%rax), %rdi
movq %rdi, %rbx
leaq 0x3595(%rip), %rsi      # 0x6fd2
callq 0x3cd5
testl %eax, %eax
je 0x3b78
movq %rbx, %rdi
leaq 0x354e(%rip), %rsi      # 0x6fa2
callq 0x3cd5
testl %eax, %eax
jne 0x3cba
leaq 0x78b8(%rip), %rax      # 0xb320
movl $0x1, 0x10(%rax)
jmp 0x3b8e
movq (%rax), %rbp
movq %rbp, %rdi
leaq 0x2baa(%rip), %rsi      # 0x662b
callq 0x3cd5
testl %eax, %eax
je 0x3b9b
movq %rbp, %rdi
leaq 0x2b98(%rip), %rsi      # 0x6630
callq 0x3cd5
testl %eax, %eax
je 0x3bca
movq %rbp, %rdi
leaq 0x2b86(%rip), %rsi      # 0x6635
callq 0x3cd5
testl %eax, %eax
jne 0x3cc3
leaq 0x785d(%rip), %rax      # 0xb320
movl $0x3, (%rax)
movaps 0x3490(%rip), %xmm0     # 0x6f60
movups %xmm0, 0xc(%rax)
movl $0x10000, 0x1c(%rax)    # imm = 0x10000
movl $0x10000, 0x10(%rsp)    # imm = 0x10000
xorl %ebp, %ebp
movl $0x3, 0x8(%rsp)
jmp 0x3bfb
cmpl $0x1, 0x8(%rsp)
je 0x3ca8
leaq 0x781c(%rip), %rax      # 0xb320
movl $0x1, 0xc(%rax)
movl $0x1, %ebp
jmp 0x3c02
testl %ebx, %ebx
jne 0x3c96
leaq 0x77fc(%rip), %rax      # 0xb320
movl $0x1, 0x4(%rax)
jmp 0x3c02
testl %ebp, %ebp
jne 0x3c9f
leaq 0x77e1(%rip), %rax      # 0xb320
movl $0x1, 0x14(%rax)
jmp 0x3c02
movq (%rax), %rdi
callq 0x3dd2
testl %eax, %eax
je 0x3c8d
cmpl 0x10(%rsp), %eax
ja 0x3cb1
leaq 0x77b4(%rip), %rcx      # 0xb320
movl %eax, 0x1c(%rcx)
movl %eax, 0x10(%rsp)
jmp 0x3bfb
testl %ebp, %ebp
jne 0x3ccc
leaq 0x7799(%rip), %rax      # 0xb320
movl $0x0, 0x10(%rax)
leaq 0x33eb(%rip), %rsi      # 0x6f80
movl 0x1c(%rsp), %ebx
jmp 0x3c02
leaq 0x777e(%rip), %rax      # 0xb320
movl $0x1, (%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movl $0x1100, 0x1c(%rax)     # imm = 0x1100
movl $0x1100, 0x10(%rsp)     # imm = 0x1100
xorl %ebp, %ebp
movl $0x1, 0x8(%rsp)
jmp 0x3bfb
leaq 0x774f(%rip), %rax      # 0xb320
movl $0x2, (%rax)
movaps 0x3382(%rip), %xmm0     # 0x6f60
movups %xmm0, 0xc(%rax)
movl $0x1000, 0x1c(%rax)     # imm = 0x1000
movl $0x1000, 0x10(%rsp)     # imm = 0x1000
xorl %ebp, %ebp
movl $0x2, 0x8(%rsp)
leaq 0x337e(%rip), %rsi      # 0x6f80
movl %r14d, %eax
shlq $0x4, %rax
addq %rsp, %rax
addq $0x30, %rax
movl 0x8(%rax), %ecx
incl %r14d
cmpl $0xff, %ecx
jne 0x39f2
movl %r12d, %eax
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x36a0(%rip), %r13      # 0x72de
jmp 0x37f9
leaq 0x36a5(%rip), %r13      # 0x72ef
jmp 0x37f9
leaq 0x366a(%rip), %r13      # 0x72c0
jmp 0x37f9
leaq 0x3632(%rip), %r13      # 0x7294
movl $0x100, %r12d           # imm = 0x100
jmp 0x37f9
leaq 0x33aa(%rip), %r13      # 0x701e
jmp 0x37f9
movl $0x101, %r12d           # imm = 0x101
jmp 0x37f9
leaq 0x35ab(%rip), %r13      # 0x7236
jmp 0x3c62
leaq 0x33a2(%rip), %r13      # 0x7036
jmp 0x3c62
leaq 0x356d(%rip), %r13      # 0x720a
jmp 0x3c62
leaq 0x3415(%rip), %r13      # 0x70bb
jmp 0x3c62
leaq 0x34e6(%rip), %r13      # 0x7195
jmp 0x3c62
leaq 0x33c7(%rip), %r13      # 0x707f
jmp 0x3c62
leaq 0x348b(%rip), %r13      # 0x714c
jmp 0x3c62
leaq 0x34f7(%rip), %r13      # 0x71c1
jmp 0x3c62
leaq 0x3436(%rip), %r13      # 0x7109
jmp 0x3c62