// File: /workspace/github_cpp_makefile_star2_O2/Ahhgust[P]STRaitRazor/str8.cpp
// Function: parseArgs(int, char**, Options&)
int
parseArgs(int argc, char **argv, Options &opt) {
  
  int i;

  // defaults
  opt.out = stdout;
  opt.verbose=0;
  opt.help=0;
  opt.shortCircuit=0;
  opt.minPrint=0;
  opt.noReverseComplement=0; 
  opt.config=NULL;
  opt.numThreads=1;
  opt.useTrie=1;
  opt.type=NULL;
  opt.includeAnchors=false;
  opt.printHeader=false;
  opt.motifDistance=0;
  opt.distance=1;
  opt.useQuality=NO_QUALITY;

  bool errors=0;
  
  for (i=1; i < argc; ++i) {
    if (argv[i][0] == '-') {
      if (argv[i][1] == 'h') {
        opt.help=1;
      } else if (argv[i][1] == 'd') {
        opt.printHeader=1;
      } else if (argv[i][1] == 's') {
        opt.shortCircuit=1;
      } else if (argv[i][1] == 'v') {
        opt.verbose=1;
      } else if (argv[i][1] == 'i') {
        opt.includeAnchors=true;
      } else if (argv[i][1] == 'q') {
        opt.useQuality=EXPECT_QUALITY;

        // my attempt at an optional argument
        ++i;
        if (argv[i] == NULL)
          break;
        else if (argv[i][1] == '\0') {
          if (argv[i][0] == 'x' || argv[i][0] == 'X') {
            opt.useQuality = EXPECT_QUALITY;
          } else if (argv[i][0] == 'e' || argv[i][0] == 'E') {
            opt.useQuality = EDGAR_QUALITY;
          } else {
            --i;
          }
        } else {
          --i;
        }

        
      } else if (argv[i][1] == 't') {
        // filters the config file by type
        ++i;
        opt.type = argv[i];
        if (opt.type==NULL) {
          cerr << "Oops. -t flag requires a type!" << endl;
          errors=1;
        }
      } else if (argv[i][1] == 'n') {
        opt.noReverseComplement=1; 
      } else if (argv[i][1] == 'o') { // setting output file
        if (i == argc-1) {
          cerr << endl<< "Option -o requires an argument\nEG, -o outFile.txt" << endl << endl;
          errors=1;
        } else {
          ++i;
          opt.out = fopen(argv[i], "w");
        }
      } else if (argv[i][1] == 'f') { // setting min records to print
        if (i == argc-1) {
          cerr << endl << "Option -f requires an integer; the smallest number of haplotype-counts that are allowed to be printed" << endl << endl;
          errors=1;
        } else {
          ++i;
          char *s = argv[i];
          while (*s >= '0' && *s <= '9') {
            opt.minPrint = (opt.minPrint*10)+(*s - '0');
            ++s;
          }
          if (s == argv[i]) {
            cerr << endl << "Option -f requires an integer; the smallest number of haplotype-counts that are allowed to be printed, not " << s  << endl << endl;
            errors=1;
          }
        }
      } else if (argv[i][1] == 'a') { // setting the degeneracy/distance with anchors when constructing the trie
        if (i == argc-1) {
          cerr << endl << "Option -a requires an integer in the range [0,2] (inclusive); the (max) hamming distance used when searching for anchors" << endl << endl;
          errors=1;
        } else {
          ++i;
          char *s = argv[i];
          opt.distance = (*s - '0');
          if (s[1] != 0 || opt.distance > 2) {
            cerr << endl << "Option -a requires a an integer in the range [0,2] (inclusive); the (max) hamming distance used when searching for anchors, not: " << s << endl;
            errors=1;
          }
          //	  cerr << "Distance is " << ((unsigned)opt.distance) << endl;
        }
      } else if (argv[i][1] == 'm') { // setting the degeneracy/distance with motifs when constructing the trie
        if (i == argc-1) {
          cerr << endl << "Option -m requires a 0 or a 1; the (max) hamming distance used when searching for motifs" << endl << endl;
	  errors=1;
        } else {
          ++i;
          char *s = argv[i];
          opt.motifDistance = (*s - '0');
          if (s[1] != 0 || opt.motifDistance > 1) {
            cerr << endl << "Option -m requires a 0 or a 1 (inclusive); the (max) hamming distance used when searching for motifs, not: " << s << endl;
            errors=1;
          }
        }
      } else if (argv[i][1] == 'p') { // setting the number of threads/processors
        if (i == argc-1) {
          cerr << endl << "Option -p requires an integer; the number of processors needed" << endl << endl;
          errors=1;
        } else {
          ++i;
          char *s = argv[i];
          opt.numThreads=0;
          while (*s >= '0' && *s <= '9') {
            opt.numThreads = (opt.numThreads*10)+(*s - '0');
            ++s;
          }
          if (s == argv[i]) {
            cerr << endl << "Option -p requires an integer; not " << s  << endl << endl;
            errors=1;
          }
          
#ifdef NOTHREADS
          
          if (opt.numThreads > 1) {
            cerr << "This program was compiled w/o threads, yet you are trying to use multithreading. You can't do both!" << endl <<
              "Please either recompile this program with threads, or set the number of threads to 1!!" << endl;
            exit(EXIT_FAILURE);
          } 
#endif
          
        }
      } else if (argv[i][1] == 'c') { // this config file
        if (i == argc-1) {
          cerr << endl<< "Option -c requires a file; ie, the config file" << endl << endl;
          errors=1;
        } else {
          ++i;
          opt.config = argv[i];
        }
      } else if (argv[i][1] == '-') { // unix convention; force the end of flags
        break;
      } else {
        cerr << endl <<  "Unknown option: " << argv[i]  << endl << endl;
        errors=1;
      }

    } else
      break;
    
  }
  
  if (opt.config==NULL) {
    cerr << endl <<  "Missing required flag: -c configfile"  << endl << endl;
    errors=1;
  }

  if (errors || opt.help) 
    usage(argv[0]);

  return i;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movq 0x9e7f(%rip), %rax      # 0xefb0
movq (%rax), %rax
movq %rax, 0x10(%rdx)
andq $0x0, 0x18(%rdx)
andq $0x0, (%rdx)
movl $0x1, 0x20(%rdx)
movb $0x1, 0x27(%rdx)
andq $0x0, 0x28(%rdx)
movl %edi, %r15d
andw $0x0, 0x8(%rdx)
movw $0x1, 0x25(%rdx)
movb $0x0, 0xa(%rdx)
leal -0x1(%r15), %edi
pushq $0x1
popq %rbp
xorl %r9d, %r9d
movq 0x9e7c(%rip), %r12      # 0xeff0
leaq 0x4ee5(%rip), %r8       # 0xa060
movl %edi, 0xc(%rsp)
cmpl %r15d, %ebp
jge 0x551f
movslq %ebp, %r13
movq (%rbx,%r13,8), %rax
cmpb $0x2d, (%rax)
jne 0x551f
movzbl 0x1(%rax), %eax
leal -0x61(%rax), %ecx
cmpl $0x15, %ecx
ja 0x535b
movslq (%r8,%rcx,4), %rax
addq %r8, %rax
jmpq *%rax
cmpl %edi, %ebp
jne 0x5397
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x5820(%rip), %rsi      # 0xa9eb
jmp 0x52db
movb $0x1, 0x5(%r14)
jmp 0x54db
incl %ebp
movq 0x8(%rbx,%r13,8), %rax
movq %rax, 0x28(%r14)
testq %rax, %rax
jne 0x54db
movq %r12, %rdi
leaq 0x56ce(%rip), %rsi      # 0xa8c6
jmp 0x54c0
movb $0x1, 0x4(%r14)
jmp 0x54db
cmpl %edi, %ebp
jne 0x5387
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x59ed(%rip), %rsi      # 0xac0e
jmp 0x52db
movb $0x1, 0x7(%r14)
jmp 0x54db
cmpl %edi, %ebp
jne 0x53d6
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x5961(%rip), %rsi      # 0xabab
jmp 0x52db
cmpl %edi, %ebp
jne 0x5421
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x56b0(%rip), %rsi      # 0xa919
jmp 0x52db
movb $0x1, 0x9(%r14)
jmp 0x54db
movb $0x2, 0xa(%r14)
leal 0x1(%rbp), %eax
movq 0x8(%rbx,%r13,8), %rcx
testq %rcx, %rcx
je 0x551d
cmpb $0x0, 0x1(%rcx)
jne 0x54db
movzbl (%rcx), %ecx
cmpl $0x45, %ecx
je 0x5516
cmpl $0x78, %ecx
je 0x54dd
cmpl $0x65, %ecx
je 0x5516
cmpl $0x58, %ecx
je 0x54dd
jmp 0x54db
cmpl %edi, %ebp
jne 0x547f
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x580b(%rip), %rsi      # 0xaae6
callq 0x3240
movq %rax, %rdi
callq 0x3130
movq %rax, %rdi
callq 0x3130
leaq 0x4d69(%rip), %r8       # 0xa060
movl 0xc(%rsp), %edi
movb $0x1, %r9b
movl %edi, %eax
jmp 0x54dd
movb $0x1, 0x6(%r14)
jmp 0x54db
movq %r15, 0x10(%rsp)
cmpl %edi, %ebp
movl %edi, %r15d
jne 0x54e6
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x55b4(%rip), %rsi      # 0xa8e5
callq 0x3240
movq %rax, %rdi
callq 0x3130
movq %rax, %rdi
callq 0x3130
movb $0x1, %r9b
movl %r15d, %eax
jmp 0x5505
movb $0x1, 0x8(%r14)
jmp 0x54db
cmpl $0x2d, %eax
je 0x551f
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x58c7(%rip), %rsi      # 0xac3d
callq 0x3240
movq (%rbx,%r13,8), %rsi
movq %rax, %rdi
jmp 0x5470
incl %ebp
movq 0x8(%rbx,%r13,8), %rax
movq %rax, 0x18(%r14)
jmp 0x54db
incl %ebp
movq 0x8(%rbx,%r13,8), %r13
movb (%r13), %al
addb $-0x30, %al
movb %al, 0x25(%r14)
cmpb $0x0, 0x1(%r13)
setne %cl
cmpb $0x3, %al
setae %al
orb %cl, %al
cmpb $0x1, %al
jne 0x54db
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x5693(%rip), %rsi      # 0xaa64
jmp 0x54b5
movq 0x8(%rbx,%r13,8), %r13
andl $0x0, 0x20(%r14)
incl %ebp
xorl %eax, %eax
xorl %ecx, %ecx
movb (%r13,%rax), %dl
addb $-0x30, %dl
cmpb $0x9, %dl
ja 0x5404
imull $0xa, %ecx, %esi
movzbl %dl, %ecx
addl %esi, %ecx
movl %ecx, 0x20(%r14)
incq %rax
jmp 0x53e6
testq %rax, %rax
jne 0x54db
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x57cb(%rip), %rsi      # 0xabea
jmp 0x5465
incl %ebp
movq 0x8(%rbx,%r13,8), %r13
movl (%r14), %ecx
xorl %eax, %eax
movb (%r13,%rax), %dl
addb $-0x30, %dl
cmpb $0x9, %dl
ja 0x544a
imull $0xa, %ecx, %esi
movzbl %dl, %ecx
addl %esi, %ecx
movl %ecx, (%r14)
incq %rax
jmp 0x542d
testq %rax, %rax
jne 0x54db
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x551a(%rip), %rsi      # 0xa97f
callq 0x3240
movq %rax, %rdi
movq %r13, %rsi
callq 0x3240
movq %rax, %rdi
callq 0x3130
jmp 0x54c5
incl %ebp
movq 0x8(%rbx,%r13,8), %r13
movb (%r13), %al
addb $-0x30, %al
movb %al, 0x26(%r14)
cmpb $0x0, 0x1(%r13)
setne %cl
cmpb $0x2, %al
setae %al
orb %cl, %al
cmpb $0x1, %al
jne 0x54db
movq %r12, %rdi
callq 0x3130
movq %rax, %rdi
leaq 0x568a(%rip), %rsi      # 0xab3f
callq 0x3240
movq %rax, %rdi
movq %r13, %rsi
callq 0x3240
movq %rax, %rdi
callq 0x3130
leaq 0x4b8c(%rip), %r8       # 0xa060
movl 0xc(%rsp), %edi
movb $0x1, %r9b
movl %ebp, %eax
incl %eax
movl %eax, %ebp
jmp 0x517f
incl %ebp
movq 0x8(%rbx,%r13,8), %rdi
leaq 0x5423(%rip), %rsi      # 0xa917
movq %r9, %r13
callq 0x32d0
movq %r13, %r9
movq %rax, 0x10(%r14)
movl %ebp, %eax
movl %r15d, %edi
movq 0x10(%rsp), %r15
leaq 0x4b4c(%rip), %r8       # 0xa060
jmp 0x54dd
movb $0x1, 0xa(%r14)
jmp 0x54dd
movl %eax, %ebp
cmpq $0x0, 0x18(%r14)
je 0x5544
testb $0x1, %r9b
jne 0x556f
cmpb $0x1, 0x6(%r14)
je 0x556f
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x9aa5(%rip), %rdi      # 0xeff0
callq 0x3130
leaq 0x56f7(%rip), %rsi      # 0xac4e
movq %rax, %rdi
callq 0x3240
movq %rax, %rdi
callq 0x3130
movq %rax, %rdi
callq 0x3130
movq (%rbx), %rdi
callq 0x4efd