// File: myudelson[P]hmm-scalable/predicthmm.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':
				param.quiet = (NPAR)atoi(argv[i]);
				if(param.quiet!=0 && param.quiet!=1) {
					fprintf(stderr,"ERROR! Quiet param should be 0 or 1\n");
					exit_with_help();
				}
				break;
            case  'd':
				param.multiskill = argv[i][0]; // just grab first character (later, maybe several)
                break;
			case 'b':
                param.binaryinput = atoi( strtok(argv[i],"\t\n\r"));
                break;
            case  'p':
				param.predictions = atoi(argv[i]);
				if(param.predictions<0 || param.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':
				param.sliced = (NPAR)atoi(argv[i]);
				if(param.sliced!=0 && param.sliced!=1) {
					fprintf(stderr,"ERROR! Time parameter should be either 0 (off) or 1(on)\n");
					exit_with_help();
				}
				break;
            case  'U':
                param.update_known = *strtok(argv[i],",\t\n\r");
                ch = strtok(NULL, ",\t\n\r");
                param.update_unknown = ch[0];
                
                if( (param.update_known!='r' && param.update_known!='g') ||
                   (param.update_unknown!='t' && param.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(param.initfile, argv[i]);
                        break;
                    }
                }
                // init parameters
                if(param.init_params!=NULL) free(param.init_params);
                param.init_params = Calloc(NUMBER, (size_t)n);
                param.init_params_n = (NPAR)n;
                // read params and write to params
                param.init_params[0] = atof( strtok(argv[i],",\t\n\r") );
                for(int j=1; j<n; j++) {
                    param.init_params[j] = atof( strtok(NULL,",\t\n\r") );
                }
                break;
			default:
				fprintf(stderr,"unknown option: -%c\n", argv[i-1][1]);
				exit_with_help();
				break;
		}
	}   
    if(param.cv_target_obs>0 && param.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
            param.predictions = 0;
        }
		else {
            // param.predictions = 1;
			strcpy(predict_file_name,argv[i]);
        }
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %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 0x674f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x6377
jmp 0x674f
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
cmpl -0x4(%rbp), %eax
jl 0x638a
callq 0x6830
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, -0x50(%rbp)
subl $0x44, %eax
ja 0x670d
movq -0x50(%rbp), %rax
leaq 0x48c91(%rip), %rcx     # 0x4f04c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x5490
movb %al, 0x54f99(%rip)      # 0x5b374
movsbl 0x54f92(%rip), %eax     # 0x5b374
cmpl $0x0, %eax
je 0x6410
movsbl 0x54f86(%rip), %eax     # 0x5b374
cmpl $0x1, %eax
je 0x6410
movq 0x54bde(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x4947e(%rip), %rsi     # 0x4f882
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
movb %al, 0x55827(%rip)      # 0x5bc50
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x494f8(%rip), %rsi     # 0x4f939
callq 0x54a0
movq %rax, %rdi
callq 0x5490
movl %eax, 0x54f4c(%rip)     # 0x5b3a0
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x5490
movl %eax, 0x54f28(%rip)     # 0x5b398
cmpl $0x0, 0x54f21(%rip)     # 0x5b398
jl 0x6482
cmpl $0x3, 0x54f18(%rip)     # 0x5b398
jle 0x649f
movq 0x54b4f(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x49414(%rip), %rsi     # 0x4f8a7
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x5490
movb %al, 0x54eb0(%rip)      # 0x5b36b
movsbl 0x54ea9(%rip), %eax     # 0x5b36b
cmpl $0x0, %eax
je 0x64f0
movsbl 0x54e9d(%rip), %eax     # 0x5b36b
cmpl $0x1, %eax
je 0x64f0
movq 0x54afe(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x4941b(%rip), %rsi     # 0x4f8ff
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x49430(%rip), %rsi     # 0x4f938
callq 0x54a0
movb (%rax), %al
movb %al, 0x54e87(%rip)      # 0x5b39c
xorl %eax, %eax
movl %eax, %edi
leaq 0x49418(%rip), %rsi     # 0x4f938
callq 0x54a0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movb (%rax), %al
movb %al, 0x54e68(%rip)      # 0x5b39d
movsbl 0x54e60(%rip), %eax     # 0x5b39c
cmpl $0x72, %eax
je 0x654d
movsbl 0x54e54(%rip), %eax     # 0x5b39c
cmpl $0x67, %eax
jne 0x6565
movsbl 0x54e49(%rip), %eax     # 0x5b39d
cmpl $0x74, %eax
je 0x6582
movsbl 0x54e3d(%rip), %eax     # 0x5b39d
cmpl $0x67, %eax
je 0x6582
movq 0x54a6c(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x493c7(%rip), %rsi     # 0x4f93d
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x673f
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x5130
movl %eax, -0x3c(%rbp)
movl $0x1, -0x30(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x3c(%rbp), %eax
jge 0x666a
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 0x660e
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 0x6640
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 0x665a
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 0x665a
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq 0x54d51(%rip), %rdi     # 0x5b3a4
callq 0x5290
jmp 0x666a
jmp 0x665c
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x65a9
cmpq $0x0, 0x54cce(%rip)     # 0x5b340
je 0x6680
movq 0x54cc5(%rip), %rdi     # 0x5b340
callq 0x5380
movslq -0x30(%rbp), %rdi
movl $0x8, %esi
callq 0x5180
movq %rax, 0x54cab(%rip)     # 0x5b340
movl -0x30(%rbp), %eax
movb %al, 0x54caa(%rip)      # 0x5b348
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0x49287(%rip), %rsi     # 0x4f938
callq 0x54a0
movq %rax, %rdi
callq 0x53c0
movq 0x54c7b(%rip), %rax     # 0x5b340
movsd %xmm0, (%rax)
movl $0x1, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x670b
xorl %eax, %eax
movl %eax, %edi
leaq 0x49255(%rip), %rsi     # 0x4f938
callq 0x54a0
movq %rax, %rdi
callq 0x53c0
movq 0x54c49(%rip), %rax     # 0x5b340
movslq -0x44(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x66d0
jmp 0x673f
movq 0x548c4(%rip), %rax     # 0x5afd8
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 0x49274(%rip), %rsi     # 0x4f9a7
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x6741
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6352
movsbl 0x55050(%rip), %eax     # 0x5b7a6
cmpl $0x0, %eax
jle 0x6781
cmpl $0x0, 0x54c2e(%rip)     # 0x5b390
jle 0x6781
movq 0x5486d(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x49247(%rip), %rsi     # 0x4f9bc
movb $0x0, %al
callq 0x5440
callq 0x6830
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x678e
callq 0x6830
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 0x5290
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x67d4
movq 0x5481c(%rip), %rax     # 0x5afd8
movq (%rax), %rdi
leaq 0x49225(%rip), %rsi     # 0x4f9eb
movb $0x0, %al
callq 0x5440
callq 0x6830
jmp 0x681e
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 0x5290
movl -0x2c(%rbp), %eax
cmpl -0x4(%rbp), %eax
jl 0x6807
movl $0x0, 0x54b93(%rip)     # 0x5b398
jmp 0x681c
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x5290
jmp 0x681e
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)