// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x168, %rsp            # imm = 0x168
movl %edi, 0x160(%rsp)
movq %rsi, 0x158(%rsp)
movl $0x0, 0x14(%rsp)
cmpl $0x11, 0x14(%rsp)
jae 0x5734
movl 0x14(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq $0x0, (%rax)
movl 0x14(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movl $0xff, 0x8(%rax)
movl 0x14(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14(%rsp)
jmp 0x56ee
cmpl $0x2, 0x160(%rsp)
jge 0x575c
leaq 0x486c(%rip), %rdi      # 0x9fb1
movb $0x0, %al
callq 0x1040
movl $0x0, 0x164(%rsp)
jmp 0x5e56
movq 0x158(%rsp), %rax
movq 0x8(%rax), %rdi
addq $0x1, %rdi
leaq 0x47c5(%rip), %rsi      # 0x9f38
callq 0x5e70
cmpl $0x0, %eax
je 0x579e
movq 0x158(%rsp), %rax
movq 0x8(%rax), %rdi
addq $0x1, %rdi
leaq 0x4854(%rip), %rsi      # 0x9fe8
callq 0x5e70
cmpl $0x0, %eax
jne 0x57ae
movl $0x1, 0x164(%rsp)
jmp 0x5e56
movl $0x1, 0x34(%rsp)
movl $0x0, 0x30(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x34(%rsp), %ecx
xorl %eax, %eax
cmpl 0x160(%rsp), %ecx
movb %al, 0x13(%rsp)
jae 0x57f6
movq 0x158(%rsp), %rax
movl 0x34(%rsp), %ecx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
sete %al
movb %al, 0x13(%rsp)
movb 0x13(%rsp), %al
testb $0x1, %al
jne 0x5803
jmp 0x58ae
movq 0x158(%rsp), %rax
movl 0x34(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
addq $0x1, %rdi
callq 0x5f90
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x38(%rsp)
je 0x5880
cmpl $0x10, 0x30(%rsp)
jb 0x584e
leaq 0x47b6(%rip), %rdi      # 0x9fed
movb $0x0, %al
callq 0x1040
movl $0x101, 0x164(%rsp) # imm = 0x101
jmp 0x5e56
movl 0x30(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x30(%rsp)
movl %eax, %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x38(%rsp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
jmp 0x589e
leaq 0x477b(%rip), %rdi      # 0xa002
movb $0x0, %al
callq 0x1040
movl $0x101, 0x164(%rsp) # imm = 0x101
jmp 0x5e56
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x57c6
jmp 0x58b0
movl 0x34(%rsp), %eax
cmpl 0x160(%rsp), %eax
jae 0x5990
cmpl $0x2, 0x2c(%rsp)
jb 0x58e6
leaq 0x4745(%rip), %rdi      # 0xa014
movb $0x0, %al
callq 0x1040
movl $0x101, 0x164(%rsp) # imm = 0x101
jmp 0x5e56
movq 0x158(%rsp), %rax
movl 0x34(%rsp), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x1050
movq %rax, %rdi
addq $0x1, %rdi
callq 0x10d0
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x20(%rsp)
jne 0x5932
leaq 0x4718(%rip), %rdi      # 0xa033
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
movq 0x20(%rsp), %rdi
movq 0x158(%rsp), %rax
movl 0x34(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x1070
cmpl $0x0, 0x2c(%rsp)
jne 0x5965
movq 0x20(%rsp), %rcx
leaq 0x8a41(%rip), %rax      # 0xe3a0
movq %rcx, 0x20(%rax)
jmp 0x5975
movq 0x20(%rsp), %rcx
leaq 0x8a2f(%rip), %rax      # 0xe3a0
movq %rcx, 0x28(%rax)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x58b0
cmpl $0x0, 0x2c(%rsp)
jne 0x59b5
leaq 0x46c2(%rip), %rdi      # 0xa060
movb $0x0, %al
callq 0x1040
movl $0x101, 0x164(%rsp) # imm = 0x101
jmp 0x5e56
leaq 0x40(%rsp), %rdi
movl $0x10, %esi
callq 0x6020
movl $0x0, 0x30(%rsp)
movl $0x0, 0x1c(%rsp)
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
cmpl $0xff, 0x8(%rax)
je 0x5e4b
movl 0x1c(%rsp), %eax
movl 0x30(%rsp), %ecx
movl %ecx, %edx
leaq 0x40(%rsp), %rcx
shlq $0x4, %rdx
addq %rdx, %rcx
cmpl 0x8(%rcx), %eax
jne 0x5a2c
leaq 0x4664(%rip), %rdi      # 0xa079
movb $0x0, %al
callq 0x1040
movl $0x101, 0x164(%rsp) # imm = 0x101
jmp 0x5e56
movl 0x30(%rsp), %eax
shlq $0x4, %rax
movl 0x48(%rsp,%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, 0x8(%rsp)
subl $0x6, %eax
ja 0x5e07
movq 0x8(%rsp), %rax
leaq 0x44c2(%rip), %rcx      # 0x9f18
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x893a(%rip), %rax      # 0xe3a0
movl $0x1, 0x8(%rax)
jmp 0x5e22
leaq 0x8927(%rip), %rax      # 0xe3a0
cmpl $0x0, 0x8(%rax)
je 0x5a9d
leaq 0x4609(%rip), %rdi      # 0xa08f
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
leaq 0x88fc(%rip), %rax      # 0xe3a0
movl $0x1, 0x4(%rax)
jmp 0x5e22
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
leaq 0x4143(%rip), %rsi      # 0x9c0f
callq 0x5e70
cmpl $0x0, %eax
jne 0x5b2e
leaq 0x88c3(%rip), %rax      # 0xe3a0
movl $0x1, (%rax)
leaq 0x88b6(%rip), %rax      # 0xe3a0
movl $0x0, 0xc(%rax)
leaq 0x88a8(%rip), %rax      # 0xe3a0
movl $0x0, 0x10(%rax)
leaq 0x889a(%rip), %rax      # 0xe3a0
movl $0x0, 0x14(%rax)
leaq 0x888c(%rip), %rax      # 0xe3a0
movl $0x0, 0x18(%rax)
leaq 0x887e(%rip), %rax      # 0xe3a0
movl $0x1100, 0x1c(%rax)     # imm = 0x1100
jmp 0x5c49
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
leaq 0x40ca(%rip), %rsi      # 0x9c14
callq 0x5e70
cmpl $0x0, %eax
jne 0x5bac
leaq 0x8845(%rip), %rax      # 0xe3a0
movl $0x2, (%rax)
leaq 0x8838(%rip), %rax      # 0xe3a0
movl $0x0, 0xc(%rax)
leaq 0x882a(%rip), %rax      # 0xe3a0
movl $0x1, 0x10(%rax)
leaq 0x881c(%rip), %rax      # 0xe3a0
movl $0x0, 0x14(%rax)
leaq 0x880e(%rip), %rax      # 0xe3a0
movl $0x1, 0x18(%rax)
leaq 0x8800(%rip), %rax      # 0xe3a0
movl $0x1000, 0x1c(%rax)     # imm = 0x1000
jmp 0x5c47
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
leaq 0x4051(%rip), %rsi      # 0x9c19
callq 0x5e70
cmpl $0x0, %eax
jne 0x5c27
leaq 0x87c7(%rip), %rax      # 0xe3a0
movl $0x3, (%rax)
leaq 0x87ba(%rip), %rax      # 0xe3a0
movl $0x0, 0xc(%rax)
leaq 0x87ac(%rip), %rax      # 0xe3a0
movl $0x1, 0x10(%rax)
leaq 0x879e(%rip), %rax      # 0xe3a0
movl $0x0, 0x14(%rax)
leaq 0x8790(%rip), %rax      # 0xe3a0
movl $0x1, 0x18(%rax)
leaq 0x8782(%rip), %rax      # 0xe3a0
movl $0x10000, 0x1c(%rax)    # imm = 0x10000
jmp 0x5c45
leaq 0x448e(%rip), %rdi      # 0xa0bc
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
jmp 0x5c47
jmp 0x5c49
jmp 0x5e22
movl $0x1, %eax
leaq 0x8746(%rip), %rcx      # 0xe3a0
cmpl (%rcx), %eax
jne 0x5c7c
leaq 0x44a1(%rip), %rdi      # 0xa106
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
leaq 0x871d(%rip), %rax      # 0xe3a0
movl $0x1, 0xc(%rax)
jmp 0x5e22
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
leaq 0x42bf(%rip), %rsi      # 0x9f6a
callq 0x5e70
cmpl $0x0, %eax
jne 0x5cf0
leaq 0x86e4(%rip), %rax      # 0xe3a0
cmpl $0x0, 0xc(%rax)
je 0x5ce0
leaq 0x446a(%rip), %rdi      # 0xa133
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
leaq 0x86b9(%rip), %rax      # 0xe3a0
movl $0x0, 0x10(%rax)
jmp 0x5d46
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
leaq 0x422e(%rip), %rsi      # 0x9f3a
callq 0x5e70
cmpl $0x0, %eax
jne 0x5d26
leaq 0x8683(%rip), %rax      # 0xe3a0
movl $0x1, 0x10(%rax)
jmp 0x5d44
leaq 0x444a(%rip), %rdi      # 0xa177
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
jmp 0x5d46
jmp 0x5e22
leaq 0x864e(%rip), %rax      # 0xe3a0
cmpl $0x0, 0xc(%rax)
je 0x5d76
leaq 0x4462(%rip), %rdi      # 0xa1c1
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
leaq 0x8623(%rip), %rax      # 0xe3a0
movl $0x1, 0x14(%rax)
jmp 0x5e22
movl 0x30(%rsp), %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x6130
movl %eax, 0x18(%rsp)
cmpl $0x0, 0x18(%rsp)
jne 0x5dcc
leaq 0x445b(%rip), %rdi      # 0xa210
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
movl 0x18(%rsp), %eax
leaq 0x85c9(%rip), %rcx      # 0xe3a0
cmpl 0x1c(%rcx), %eax
jbe 0x5df7
leaq 0x4477(%rip), %rdi      # 0xa25a
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
movl 0x18(%rsp), %ecx
leaq 0x859e(%rip), %rax      # 0xe3a0
movl %ecx, 0x1c(%rax)
jmp 0x5e22
leaq 0x4489(%rip), %rdi      # 0xa297
movb $0x0, %al
callq 0x1040
movl $0x100, 0x164(%rsp) # imm = 0x100
jmp 0x5e56
movl 0x30(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x30(%rsp)
movl %eax, %eax
movl %eax, %ecx
leaq 0x40(%rsp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, 0x1c(%rsp)
jmp 0x59d4
movl $0x2, 0x164(%rsp)
movl 0x164(%rsp), %eax
addq $0x168, %rsp            # imm = 0x168
retq
nopw %cs:(%rax,%rax)