// File: /workspace/github_c_makefile_star2_O2/sheneman[P]clearcut/cmdargs.c
// Function: NJ_handle_args
NJ_ARGS *
NJ_handle_args(int argc,
	       char *argv[]) {
  
  static NJ_ARGS nj_args;
  int option_index, c;

  struct option NJ_long_options[] = {

    /* These options don't set a flag */
    {"in",        required_argument, NULL, 'i'},
    {"out",       required_argument, NULL, 'o'},
    {"seed",      required_argument, NULL, 's'},
    {"matrixout", required_argument, NULL, 'm'},
    {"ntrees",    required_argument, NULL, 'n'},

    /* These options set a flag */
    {"verbose",      no_argument, &(nj_args.verbose_flag),  1},
    {"quiet",        no_argument, &(nj_args.quiet_flag),    1},
    {"distance",     no_argument, &(nj_args.input_mode),    NJ_INPUT_MODE_DISTANCE}, 
    {"alignment",    no_argument, &(nj_args.input_mode),    NJ_INPUT_MODE_ALIGNED_SEQUENCES},
    {"help",         no_argument, &(nj_args.help),          1},
    {"version",      no_argument, &(nj_args.version),       1},
    {"norandom",     no_argument, &(nj_args.norandom),      1},
    {"shuffle",      no_argument, &(nj_args.shuffle),       1},
    {"stdin",        no_argument, &(nj_args.stdin_flag),    1},
    {"stdout",       no_argument, &(nj_args.stdout_flag),   1},
    {"dna",          no_argument, &(nj_args.dna_flag),      1},
    {"DNA",          no_argument, &(nj_args.dna_flag),      1},
    {"protein",      no_argument, &(nj_args.protein_flag),  1},
    {"neighbor",     no_argument, &(nj_args.neighbor),      1},
    {"expblen",      no_argument, &(nj_args.expblen),       1},
    {"expdist",      no_argument, &(nj_args.expdist),       1}, 

    {"jukes",        no_argument, &(nj_args.jukes_flag),    1},
    {"kimura",       no_argument, &(nj_args.kimura_flag),   1},
    
    {0, 0, 0, 0}

  };
  
  /* initializes options to their default */
  nj_args.infilename       = NULL;
  nj_args.outfilename      = NULL;
  nj_args.matrixout        = NULL;
  nj_args.seed             = time(0);
  nj_args.verbose_flag     = 0;
  nj_args.quiet_flag       = 0;
  nj_args.input_mode       = NJ_INPUT_MODE_DISTANCE;
  nj_args.help             = 0;
  nj_args.version          = 0;
  nj_args.norandom         = 0;
  nj_args.shuffle          = 0;
  nj_args.stdin_flag       = 0;
  nj_args.stdout_flag      = 0;
  nj_args.dna_flag         = 0;
  nj_args.protein_flag     = 0;
  nj_args.correction_model = NJ_MODEL_NONE;
  nj_args.jukes_flag       = 0;
  nj_args.kimura_flag      = 0;
  nj_args.neighbor         = 0;
  nj_args.ntrees           = 1;
  nj_args.expblen          = 0;
  nj_args.expdist          = 0;

  while(1) {
    c = getopt_long(argc,
		    argv,
		    "i:o:s:m:n:vqduahVSIOrDPjkNeE",
		    NJ_long_options,
		    &option_index);
    
    if(c == -1) {
      break;
    }

    switch(c) {

    case 0:
      if(NJ_long_options[option_index].flag) {
	break;
      }

      printf("option %s", NJ_long_options[option_index].name);
      if(optarg) {
	printf(" with arg %s", optarg);
      }
      printf("\n");
      break;

    case 'i':
      nj_args.infilename = optarg;
      break;

    case 'o':
      nj_args.outfilename = optarg;
      break;

    case 's':
      nj_args.seed = atoi(optarg);
      break;

    case 'm':
      nj_args.matrixout = optarg;
      break;

    case 'n':
      nj_args.ntrees = atoi(optarg);
      break;

    case 'v':
      nj_args.verbose_flag = 1;
      break; 

    case 'q':
      nj_args.quiet_flag = 1;
      break;

    case 'd':
      nj_args.input_mode = NJ_INPUT_MODE_DISTANCE;
      break;

    case 'a':
      nj_args.input_mode = NJ_INPUT_MODE_ALIGNED_SEQUENCES;
      break;

    case 'h':
      nj_args.help = 1;
      break;

    case 'V':
      nj_args.version = 1;
      break;

    case 'S':
      nj_args.shuffle = 1;
      break;
      
    case 'I':
      nj_args.stdin_flag = 1;
      break;

    case 'O':
      nj_args.stdin_flag = 1;
      break;

    case 'r':
      nj_args.norandom = 1;
      break;

    case 'D':
      nj_args.dna_flag = 1;
      break;

    case 'P':
      nj_args.protein_flag = 1;
      break;

    case 'j':
      nj_args.jukes_flag = 1;
      break;

    case 'k':
      nj_args.kimura_flag = 1;
      break;

    case 'N':
      nj_args.neighbor = 1;
      break;

    case 'e':
      nj_args.expblen = 1;
      break;

    case 'E':
      nj_args.expdist = 1;
      break;

   default:
     NJ_usage();
     exit(-1);
    }
  }
  
  if(optind < argc) {
    fprintf(stderr, "Clearcut: Unknown command-line argument:\n  --> %s\n", argv[optind]);
    NJ_usage();
    exit(-1);
  }
  
  if(nj_args.version) {
    printf("Clearcut Version: %s\n", NJ_VERSION);
    exit(0);
  }
  
  if(nj_args.help) {
    NJ_usage();
    exit(0);
  }
  
  /* if stdin & explicit filename are specified for input */
  if(nj_args.stdin_flag) {
    if(nj_args.infilename) {
      fprintf(stderr, "Clearcut:  Ambiguous input source specified.  Specify input filename OR stdin.\n");
      NJ_usage();
      exit(-1);
    }
  }

  /* if stdout & explicit filename are specified for output */
  if(nj_args.stdout_flag) {
    if(nj_args.outfilename) {
      fprintf(stderr, "Clearcut:  Ambiguous output specified.  Specify output filename OR stdout.\n");
      NJ_usage();
      exit(-1);
    }
  }

  /* if user did not specify stdin or filename, default to stdin */
  if(!nj_args.stdin_flag) {
    if(!nj_args.infilename) {

      fprintf(stderr, "Clearcut: No input file specified.  Using stdin.\n");
      nj_args.stdin_flag = 1;
    }
  }
  
  /* if user did not specify stdout or filename, default to stdout */
  if(!nj_args.stdout_flag) {
    if(!nj_args.outfilename) {
      
      fprintf(stderr, "Clearcut: No output file specified.  Using stdout.\n");
      nj_args.stdout_flag = 1;
    }
  }
  
  /* User must specify distance matrix or alignment */
  if(nj_args.input_mode == NJ_INPUT_MODE_UNKNOWN) {
    fprintf(stderr, "Clearcut: Must specify input type (--distance | --alignment)\n");
    NJ_usage();
    exit(-1);
  }

  /* do not allow protein or DNA options for distance matrix input */
  if(nj_args.input_mode == NJ_INPUT_MODE_DISTANCE) {
    if(nj_args.dna_flag || nj_args.protein_flag) {
      fprintf(stderr, "Clearcut:  Ambiguous arguments.  (--protein | --DNA) do not apply to distance \n");
      NJ_usage();
      exit(-1);
    }
  }
  
  /* make sure different filenames were specified for input and output */
  if(!nj_args.stdin_flag && !nj_args.stdout_flag) {

    if(!strcmp(nj_args.infilename, nj_args.outfilename)) {
      fprintf(stderr, "Clearcut: Input filename and output filename must be unique.\n");
      NJ_usage();
      exit(-1);
    }
  }

  /* make sure that user specifies DNA or Protein if dealing with alignment input */
  if(nj_args.input_mode == NJ_INPUT_MODE_ALIGNED_SEQUENCES) {
    if(!nj_args.dna_flag && !nj_args.protein_flag) {
      fprintf(stderr, "Clearcut: Must specify protein or DNA for alignment input.\n");
      NJ_usage();
      exit(-1);
    }
  }

  /* make sure that user does not specify both protein and DNA when dealing with alignment input */
  if(nj_args.input_mode == NJ_INPUT_MODE_ALIGNED_SEQUENCES) {
    if(nj_args.dna_flag && nj_args.protein_flag) {
      fprintf(stderr, "Clearcut: Specifying protein and DNA sequences are mutually exclusive options\n");
      NJ_usage();
      exit(-1);
    }
  }

  /* make sure verbose and quiet were not specified together */
  if(nj_args.verbose_flag && nj_args.quiet_flag) {
    fprintf(stderr, "Clearcut: Verbose and Quiet mode are mutually exclusive.\n");
    NJ_usage();
    exit(-1);
  }
  
  /* make sure that a correction model was specified only when providing an alignment */
  if(nj_args.input_mode == NJ_INPUT_MODE_DISTANCE) {
    if(nj_args.jukes_flag || nj_args.kimura_flag) {
      fprintf(stderr, "Clearcut:  Only specify correction model for alignment input.\n");
      NJ_usage();
      exit(-1);
    }
  } else {
    if(nj_args.jukes_flag && nj_args.kimura_flag) {
      fprintf(stderr, "Clearcut:  Only specify one correction model\n");
      NJ_usage();
      exit(-1);
    } else {
      if(nj_args.jukes_flag && !nj_args.kimura_flag) {
	nj_args.correction_model = NJ_MODEL_JUKES;
      } else if(nj_args.kimura_flag && !nj_args.jukes_flag) {
	nj_args.correction_model = NJ_MODEL_KIMURA;
      } else {
	nj_args.correction_model = NJ_MODEL_NONE;  /* DEFAULT */
      }
    }
  }
  
  /* make sure that the number of output trees is reasonable */
  if(nj_args.ntrees <= 0) {
    fprintf(stderr, "Clearcut: Number of output trees must be a positive integer.\n");
    NJ_usage();
    exit(-1);
  }
  
  /* 
   * make sure that if exponential distances are specified, 
   * we are dealing with alignment input
   */
  if(nj_args.expdist && nj_args.input_mode != NJ_INPUT_MODE_ALIGNED_SEQUENCES) {
    fprintf(stderr, "Clearcut: Exponential notation for distance matrix output requires that input be an alignment\n");
    NJ_usage();
    exit(-1);
  }
  
  return(&nj_args);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x318, %rsp            # imm = 0x318
movq %rsi, %rbx
movl %edi, %ebp
leaq 0x6063(%rip), %rsi      # 0xbad0
leaq 0x10(%rsp), %r14
movl $0x300, %edx            # imm = 0x300
movq %r14, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
movups %xmm0, 0x698f(%rip)     # 0xc418
andq $0x0, 0x6997(%rip)      # 0xc428
xorl %edi, %edi
callq 0x21c0
movl %eax, 0x69c2(%rip)      # 0xc460
andq $0x0, 0x6992(%rip)      # 0xc438
movl $0x64, 0x6980(%rip)     # 0xc430
xorps %xmm0, %xmm0
movups %xmm0, 0x6986(%rip)     # 0xc440
movups %xmm0, 0x698f(%rip)     # 0xc450
movss 0x2017(%rip), %xmm0     # 0x7ae0
movups %xmm0, 0x6994(%rip)     # 0xc464
movq $0x1, 0x6999(%rip) # 0xc474
andl $0x0, 0x699a(%rip)      # 0xc47c
leaq 0x215f(%rip), %r15      # 0x7c48
leaq 0xc(%rsp), %r12
leaq 0x1fef(%rip), %r13      # 0x7ae4
movl %ebp, %edi
movq %rbx, %rsi
movq %r15, %rdx
movq %r14, %rcx
movq %r12, %r8
callq 0x66bc
leal -0x44(%rax), %ecx
cmpl $0x32, %ecx
ja 0x5b26
movslq (%r13,%rcx,4), %rax
addq %r13, %rax
jmpq *%rax
movl $0x1, 0x691c(%rip)      # 0xc440
jmp 0x5af5
testl %eax, %eax
jne 0x5cd8
movslq 0xc(%rsp), %rax
shlq $0x5, %rax
cmpq $0x0, 0x20(%rsp,%rax)
jne 0x5af5
addq %rsp, %rax
addq $0x10, %rax
movq (%rax), %rsi
leaq 0x2115(%rip), %rdi      # 0x7c65
xorl %eax, %eax
callq 0x2100
leaq 0x7cb2(%rip), %rax      # 0xd810
movq (%rax), %rsi
testq %rsi, %rsi
je 0x5b74
leaq 0x2102(%rip), %rdi      # 0x7c6f
xorl %eax, %eax
callq 0x2100
pushq $0xa
popq %rdi
callq 0x2050
jmp 0x5af5
movl $0x1, 0x68c9(%rip)      # 0xc454
jmp 0x5af5
movl $0x1, 0x68b2(%rip)      # 0xc44c
jmp 0x5af5
movl $0x1, 0x689f(%rip)      # 0xc448
jmp 0x5af5
leaq 0x7c5b(%rip), %rax      # 0xd810
movq (%rax), %rdi
callq 0x2210
movl %eax, 0x689d(%rip)      # 0xc460
jmp 0x5af5
movl $0x1, 0x68aa(%rip)      # 0xc47c
jmp 0x5af5
movl $0x1, 0x6877(%rip)      # 0xc458
jmp 0x5af5
movl $0x1, 0x6880(%rip)      # 0xc470
jmp 0x5af5
movl $0x64, 0x6831(%rip)     # 0xc430
jmp 0x5af5
movl $0x1, 0x6842(%rip)      # 0xc450
jmp 0x5af5
leaq 0x7bf6(%rip), %rax      # 0xd810
movq (%rax), %rax
movq %rax, 0x67f4(%rip)      # 0xc418
jmp 0x5af5
movl $0x1, 0x6845(%rip)      # 0xc478
jmp 0x5af5
movl $0x66, 0x67ee(%rip)     # 0xc430
jmp 0x5af5
movl $0x1, 0x680b(%rip)      # 0xc45c
jmp 0x5af5
movl $0x1, 0x6808(%rip)      # 0xc468
jmp 0x5af5
leaq 0x7ba4(%rip), %rax      # 0xd810
movq (%rax), %rax
movq %rax, 0x67aa(%rip)      # 0xc420
jmp 0x5af5
movl $0x1, 0x67b3(%rip)      # 0xc438
jmp 0x5af5
movl $0x1, 0x67d8(%rip)      # 0xc46c
jmp 0x5af5
leaq 0x7b70(%rip), %rax      # 0xd810
movq (%rax), %rdi
callq 0x2210
movl %eax, 0x67c6(%rip)      # 0xc474
jmp 0x5af5
leaq 0x7b56(%rip), %rax      # 0xd810
movq (%rax), %rax
movq %rax, 0x6764(%rip)      # 0xc428
jmp 0x5af5
movl $0x1, 0x6769(%rip)      # 0xc43c
jmp 0x5af5
cmpl $-0x1, %eax
jne 0x6040
leaq 0x7b20(%rip), %rax      # 0xd808
movslq (%rax), %rax
cmpl %ebp, %eax
jl 0x5f21
cmpl $0x0, 0x6752(%rip)      # 0xc44c
jne 0x5f42
cmpl $0x0, 0x6741(%rip)      # 0xc448
jne 0x5f59
movl 0x672d(%rip), %edx      # 0xc440
testl %edx, %edx
setne %al
movq 0x66f9(%rip), %rsi      # 0xc418
testq %rsi, %rsi
setne %cl
andb %al, %cl
cmpb $0x1, %cl
je 0x5f65
movl 0x670e(%rip), %eax      # 0xc444
testl %eax, %eax
setne %dil
movq 0x66dd(%rip), %rcx      # 0xc420
testq %rcx, %rcx
setne %r8b
andb %dil, %r8b
cmpb $0x1, %r8b
je 0x5f78
testq %rsi, %rsi
setne %sil
testl %edx, %edx
setne %dl
orb %sil, %dl
je 0x5ee9
testl %eax, %eax
jne 0x5d79
testq %rcx, %rcx
je 0x5ebb
movl 0x66b1(%rip), %ebx      # 0xc430
cmpl $0x64, %ebx
je 0x5d9e
testl %ebx, %ebx
jne 0x5db0
movq 0x6269(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x2034(%rip), %rdi      # 0x7dcd
jmp 0x6035
movl 0x66b8(%rip), %ecx      # 0xc45c
orl 0x66ae(%rip), %ecx      # 0xc458
jne 0x5fd0
orl 0x668a(%rip), %eax      # 0xc440
jne 0x5dd3
movq 0x6659(%rip), %rdi      # 0xc418
movq 0x665a(%rip), %rsi      # 0xc420
callq 0x2170
testl %eax, %eax
je 0x6024
cmpl $0x66, %ebx
jne 0x5e02
movl 0x667a(%rip), %eax      # 0xc458
movl 0x6678(%rip), %ecx      # 0xc45c
movl %eax, %edx
orl %ecx, %edx
je 0x5fe5
testl %ecx, %ecx
setne %cl
testl %eax, %eax
setne %al
andb %cl, %al
cmpb $0x1, %al
je 0x5ffa
cmpl $0x0, 0x662f(%rip)      # 0xc438
je 0x5e18
cmpl $0x0, 0x662a(%rip)      # 0xc43c
jne 0x5f90
movl 0x664a(%rip), %eax      # 0xc468
movl 0x6648(%rip), %ecx      # 0xc46c
cmpl $0x64, %ebx
jne 0x5e45
orl %ecx, %eax
je 0x5e83
movq 0x61c4(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x2120(%rip), %rdi      # 0x7f5e
pushq $0x3e
jmp 0x6037
testl %ecx, %ecx
setne %dl
testl %eax, %eax
setne %sil
andb %dl, %sil
cmpb $0x1, %sil
je 0x600f
xorl %edx, %edx
testl %ecx, %ecx
setne %dl
testl %eax, %eax
leal 0x64(%rdx,%rdx), %edx
pushq $0x64
popq %rsi
cmovel %edx, %esi
testl %ecx, %ecx
pushq $0x65
popq %rcx
cmovnel %esi, %ecx
testl %eax, %eax
cmovel %esi, %ecx
movl %ecx, 0x65e1(%rip)      # 0xc464
cmpl $0x0, 0x65ea(%rip)      # 0xc474
jle 0x5fa8
cmpl $0x66, %ebx
je 0x5ea2
cmpl $0x0, 0x65e0(%rip)      # 0xc47c
jne 0x5fbb
leaq 0x656f(%rip), %rax      # 0xc418
addq $0x318, %rsp            # imm = 0x318
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x6136(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1ecd(%rip), %rdi      # 0x7d99
pushq $0x33
popq %rsi
pushq $0x1
popq %rdx
callq 0x2230
movl $0x1, 0x6563(%rip)      # 0xc444
pushq $0x1
popq %rax
jmp 0x5d79
movq 0x6108(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1e6d(%rip), %rdi      # 0x7d67
pushq $0x31
popq %rsi
pushq $0x1
popq %rdx
callq 0x2230
movl $0x1, 0x6531(%rip)      # 0xc440
movl 0x652f(%rip), %eax      # 0xc444
movq 0x6504(%rip), %rcx      # 0xc420
jmp 0x5d6c
movq 0x60d0(%rip), %rcx      # 0xbff8
movq (%rcx), %rdi
movq (%rbx,%rax,8), %rdx
leaq 0x1d46(%rip), %rsi      # 0x7c7c
xorl %eax, %eax
callq 0x2180
jmp 0x6040
leaq 0x1d66(%rip), %rdi      # 0x7caf
leaq 0x1d75(%rip), %rsi      # 0x7cc5
xorl %eax, %eax
callq 0x2100
jmp 0x5f5e
callq 0x604d
xorl %edi, %edi
callq 0x2220
movq 0x608c(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1d55(%rip), %rdi      # 0x7ccb
jmp 0x5fe1
movq 0x6079(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1d92(%rip), %rdi      # 0x7d1b
pushq $0x4b
jmp 0x6037
movq 0x6061(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1f83(%rip), %rdi      # 0x7f24
pushq $0x39
jmp 0x6037
movq 0x6049(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x2012(%rip), %rdi      # 0x7fcb
jmp 0x6035
movq 0x6036(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x203d(%rip), %rdi      # 0x8009
pushq $0x5e
jmp 0x6037
movq 0x6021(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1e2a(%rip), %rdi      # 0x7e0b
pushq $0x4f
jmp 0x6037
movq 0x600c(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1ea3(%rip), %rdi      # 0x7e99
pushq $0x3b
jmp 0x6037
movq 0x5ff7(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1eca(%rip), %rdi      # 0x7ed5
pushq $0x4e
jmp 0x6037
movq 0x5fe2(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1f7d(%rip), %rdi      # 0x7f9d
pushq $0x2d
jmp 0x6037
movq 0x5fcd(%rip), %rax      # 0xbff8
movq (%rax), %rcx
leaq 0x1e26(%rip), %rdi      # 0x7e5b
pushq $0x3d
popq %rsi
pushq $0x1
popq %rdx
callq 0x2230
callq 0x604d
pushq $-0x1
popq %rdi
callq 0x2220