// File: myudelson[P]hmm-scalable/predicthmmst.cpp
// Function: parse_arguments(int, char**, char*, char*, char*)
void parse_arguments(int argc, char **argv, char *input_file_name, char *model_file_name, char *predict_file_name) {
	// parse command line options, starting from 1 (0 is path to executable)
	// go in pairs, looking at whether first in pair starts with '-', if not, stop parsing arguments
	int i, n;
    char * ch;
	for(i=1;i<argc;i++)
	{
		if(argv[i][0] != '-') break; // end of options stop parsing
		if(++i>=argc)
			exit_with_help();
		switch(argv[i-1][1])
		{
			case 'q':
				task.quiet = (NPAR)atoi(argv[i]);
				if(task.quiet!=0 && task.quiet!=1) {
					fprintf(stderr,"ERROR! Quiet param should be 0 or 1\n");
					exit_with_help();
				}
				break;
            case  'd':
				task.multiskill = argv[i][0]; // just grab first character (later, maybe several)
                break;
			case 'b':
                task.binaryinput = atoi( strtok(argv[i],"\t\n\r"));
                break;
            case  'p':
				task.predictions = atoi(argv[i]);
				if(task.predictions<0 || task.predictions>3) {
					fprintf(stderr,"a flag of whether to report predictions for training data (-p) should be 0, 1, 2, or 3\n");
					exit_with_help();
				}
                break;
			case 't':
				task.sliced = (NPAR)atoi(argv[i]);
				if(task.sliced!=0 && task.sliced!=1) {
					fprintf(stderr,"ERROR! Time parameter should be either 0 (off) or 1(on)\n");
					exit_with_help();
				}
				break;
            case  'U':
                task.update_known = *strtok(argv[i],",\t\n\r");
                ch = strtok(NULL, ",\t\n\r");
                task.update_unknown = ch[0];
                
                if( (task.update_known!='r' && task.update_known!='g') ||
                   (task.update_unknown!='t' && task.update_unknown!='g') ) {
                    fprintf(stderr,"specification of how probabilities of states should be updated (-U) is incorrect, it sould be r|g[,t|g] \n");
                    exit_with_help();
                }
                break;
            case '0': // what was init_params for 'trainhmm' is now default_params for 'predicthmm'
                int len;
                len = (int)strlen( argv[i] );
                // count delimiters
                n = 1; // start with 1
                for(int j=0;j<len;j++) {
                    n += (argv[i][j]==',')?1:0;
                    if( (argv[i][j] >= 'a' && argv[i][j] <= 'z') || (argv[i][j] >= 'A' && argv[i][j] <= 'Z') ) {
                        strcpy(task.initfile, argv[i]);
                        break;
                    }
                }
                // init parameters
                if(task.init_param_values!=NULL) free(task.init_param_values);
                task.init_param_values = Calloc(NUMBER, (size_t)n);
                task.init_param_values_n = (NPAR)n;
                // read params and write to params
                task.init_param_values[0] = atof( strtok(argv[i],",\t\n\r") );
                for(int j=1; j<n; j++) {
                    task.init_param_values[j] = atof( strtok(NULL,",\t\n\r") );
                }
                break;
            case 'k':
                // ELO parameters specified as a comma-delimited list of values, first is an integer, the rest are real
                len = (int)strlen( argv[i] );
                // count delimiters
                n = 1; // start with 1
                for(int j=0;j<len;j++)
                    n += (NPAR)((argv[i][j]==',')?1:0);
                if( n < 3 ) {
                    fprintf(stderr,"To use Elo, one needs at lest three parameters; %d were specified\n",n);
                    exit_with_help();
                }
                // init params
                task.elo_param_values_n = (NPAR)(n-2); // first parameter is Elo type
                if(task.elo_param_values!=NULL) free(task.elo_param_values);
                task.elo_param_values = Calloc(NUMBER, (size_t)(n-2));
                // read params and write to params
                task.elo_type = (NPAR)atoi( strtok(argv[i],",\t\n\r") );
                task.elo_scope = (NCAT)atof( strtok(NULL,",\t\n\r") );
                for(int j=2; j<n; j++) {
                    task.elo_param_values[j-2] = atof( strtok(NULL,",\t\n\r") );
                }
                break;
			default:
				fprintf(stderr,"unknown option: -%c\n", argv[i-1][1]);
				exit_with_help();
				break;
		}
	}   
    if(task.cv_target_obs>0 && task.metrics>0) { // correct for 0-start coding
        fprintf(stderr,"values for -v and -m cannot be both non-zeros\n");
        exit_with_help();
    }
	
	// next argument should be input (training) file name
	if(i>=argc) // if not
		exit_with_help(); // leave
	
	strcpy(input_file_name, argv[i++]); // copy and advance
	
	if(i>=argc) { // no model file name specified
        fprintf(stderr,"no model file specified\n");
		exit_with_help(); // leave
	}
	else {
		strcpy(model_file_name,argv[i++]); // copy and advance
		if(i>=argc) {// no prediction file name specified
			//strcpy(predict_file_name,"predict_hmm.txt"); // the predict file too
            task.predictions = 0;
        }
		else {
            // task.predictions = 1;
			strcpy(predict_file_name,argv[i]);
        }
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jge 0x4334
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x3e07
jmp 0x4334
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
cmpl -0x4(%rbp), %eax
jl 0x3e1a
callq 0x4410
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
addl $-0x30, %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0x44, %eax
ja 0x42f2
movq -0x58(%rbp), %rax
leaq 0x171cd(%rip), %rcx     # 0x1b018
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3400
movb %al, 0x1e4d9(%rip)      # 0x22344
movsbl 0x1e4d2(%rip), %eax     # 0x22344
cmpl $0x0, %eax
je 0x3ea0
movsbl 0x1e4c6(%rip), %eax     # 0x22344
cmpl $0x1, %eax
je 0x3ea0
movq 0x1e14e(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x179e3(%rip), %rsi     # 0x1b877
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
movb %al, 0x1ed5f(%rip)      # 0x22c18
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x17a5d(%rip), %rsi     # 0x1b92e
callq 0x3410
movq %rax, %rdi
callq 0x3400
movl %eax, 0x1e48c(%rip)     # 0x22370
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3400
movl %eax, 0x1e468(%rip)     # 0x22368
cmpl $0x0, 0x1e461(%rip)     # 0x22368
jl 0x3f12
cmpl $0x3, 0x1e458(%rip)     # 0x22368
jle 0x3f2f
movq 0x1e0bf(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x17979(%rip), %rsi     # 0x1b89c
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3400
movb %al, 0x1e3f0(%rip)      # 0x2233b
movsbl 0x1e3e9(%rip), %eax     # 0x2233b
cmpl $0x0, %eax
je 0x3f80
movsbl 0x1e3dd(%rip), %eax     # 0x2233b
cmpl $0x1, %eax
je 0x3f80
movq 0x1e06e(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x17980(%rip), %rsi     # 0x1b8f4
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x17995(%rip), %rsi     # 0x1b92d
callq 0x3410
movb (%rax), %al
movb %al, 0x1e3c7(%rip)      # 0x2236c
xorl %eax, %eax
movl %eax, %edi
leaq 0x1797d(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movb (%rax), %al
movb %al, 0x1e3a8(%rip)      # 0x2236d
movsbl 0x1e3a0(%rip), %eax     # 0x2236c
cmpl $0x72, %eax
je 0x3fdd
movsbl 0x1e394(%rip), %eax     # 0x2236c
cmpl $0x67, %eax
jne 0x3ff5
movsbl 0x1e389(%rip), %eax     # 0x2236d
cmpl $0x74, %eax
je 0x4012
movsbl 0x1e37d(%rip), %eax     # 0x2236d
cmpl $0x67, %eax
je 0x4012
movq 0x1dfdc(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x1792c(%rip), %rsi     # 0x1b932
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3120
movl %eax, -0x3c(%rbp)
movl $0x1, -0x30(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x40fa
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x2c, %edx
cmovel %ecx, %eax
addl -0x30(%rbp), %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x61, %eax
jl 0x409e
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x7a, %eax
jle 0x40d0
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x41, %eax
jl 0x40ea
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x40(%rbp), %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x5a, %eax
jg 0x40ea
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x1e291(%rip), %rdi     # 0x22374
callq 0x3250
jmp 0x40fa
jmp 0x40ec
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x4039
cmpq $0x0, 0x1e1f6(%rip)     # 0x222f8
je 0x4110
movq 0x1e1ed(%rip), %rdi     # 0x222f8
callq 0x3320
movslq -0x30(%rbp), %rdi
movl $0x8, %esi
callq 0x3170
movq %rax, 0x1e1d3(%rip)     # 0x222f8
movl -0x30(%rbp), %eax
movb %al, 0x1e1d2(%rip)      # 0x22300
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x177ec(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, %rdi
callq 0x3360
movq 0x1e1a3(%rip), %rax     # 0x222f8
movsd %xmm0, (%rax)
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x419b
xorl %eax, %eax
movl %eax, %edi
leaq 0x177ba(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, %rdi
callq 0x3360
movq 0x1e171(%rip), %rax     # 0x222f8
movslq -0x44(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x4160
jmp 0x4324
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x3120
movl %eax, -0x3c(%rbp)
movl $0x1, -0x30(%rbp)
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x41ff
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x48(%rbp), %rcx
movsbl (%rax,%rcx), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x2c, %edx
cmovel %ecx, %eax
movsbl %al, %eax
addl -0x30(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x41c2
cmpl $0x3, -0x30(%rbp)
jge 0x4225
movq 0x1ddcc(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
movl -0x30(%rbp), %edx
leaq 0x17783(%rip), %rsi     # 0x1b99c
movb $0x0, %al
callq 0x33c0
callq 0x4410
movl -0x30(%rbp), %eax
subl $0x2, %eax
movb %al, 0x1e0f7(%rip)      # 0x22328
cmpq $0x0, 0x1e0e7(%rip)     # 0x22320
je 0x4247
movq 0x1e0de(%rip), %rdi     # 0x22320
callq 0x3320
movl -0x30(%rbp), %eax
subl $0x2, %eax
movslq %eax, %rdi
movl $0x8, %esi
callq 0x3170
movq %rax, 0x1e0bf(%rip)     # 0x22320
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x176b9(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, %rdi
callq 0x3400
movb %al, 0x1e091(%rip)      # 0x22318
xorl %eax, %eax
movl %eax, %edi
leaq 0x1769b(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, %rdi
callq 0x3360
cvttsd2si %xmm0, %eax
movl %eax, 0x1e073(%rip)     # 0x2231c
movl $0x2, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x42f0
xorl %eax, %eax
movl %eax, %edi
leaq 0x1766a(%rip), %rsi     # 0x1b92d
callq 0x3410
movq %rax, %rdi
callq 0x3360
movq 0x1e049(%rip), %rax     # 0x22320
movl -0x4c(%rbp), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x42b0
jmp 0x4324
movq 0x1dcdf(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %edx
leaq 0x176c7(%rip), %rsi     # 0x1b9df
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4326
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x3de2
movsbl 0x1e43b(%rip), %eax     # 0x22776
cmpl $0x0, %eax
jle 0x4366
cmpl $0x0, 0x1e019(%rip)     # 0x22360
jle 0x4366
movq 0x1dc88(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x1769a(%rip), %rsi     # 0x1b9f4
movb $0x0, %al
callq 0x33c0
callq 0x4410
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x4373
callq 0x4410
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x2c(%rbp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3250
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x43b9
movq 0x1dc37(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
leaq 0x17678(%rip), %rsi     # 0x1ba23
movb $0x0, %al
callq 0x33c0
callq 0x4410
jmp 0x4403
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x2c(%rbp)
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3250
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x43ec
movl $0x0, 0x1df7e(%rip)     # 0x22368
jmp 0x4401
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x3250
jmp 0x4403
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)