// File: trapexit[P]bbf/src/options.cpp
// Function: Options::parse(int, char* const*)
AppError
Options::parse(const int argc,
               char * const argv[])
{
  static const char short_options[] = "hqft:r:s:S:e:o:i:c:";
  static const struct option long_options[] =
    {
      {"help",              no_argument, NULL, 'h'},
      {"quiet",             no_argument, NULL, 'q'},
      {"force",             no_argument, NULL, 'f'},
      {"rwtype",      required_argument, NULL, 't'},
      {"retries",     required_argument, NULL, 'r'},
      {"start-block", required_argument, NULL, 's'},
      {"end-block",   required_argument, NULL, 'e'},
      {"stepping",    required_argument, NULL, 'S'},
      {"output",      required_argument, NULL, 'o'},
      {"input",       required_argument, NULL, 'i'},
      {"captcha",     required_argument, NULL, 'c'},
      {"max-errors",  required_argument, NULL, 'M'},
      {NULL,                          0, NULL,   0}
    };

  if(argc == 1)
    {
      usage(std::cout);
      return AppError::success();
    }

  opterr = 0;
  while(true)
    {
      int rv;
      AppError error;

      rv = getopt_long(argc,argv,short_options,long_options,NULL);
      if(rv == -1)
        break;

      error = process_arg(argc,argv,rv);
      if(!error.succeeded())
        return error;
    }

  if(argc == optind)
    return AppError::argument_required("instruction");
  if(argc == (optind + 1))
    return AppError::argument_required("target");

  instruction = instr_from_string(argv[optind]);
  device      = argv[optind+1];

  return validate();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq %rdi, -0xf8(%rbp)
movq %rdi, %rax
movq %rax, -0xf0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xe8(%rbp)
cmpl $0x1, -0x14(%rbp)
jne 0x19ff9
movq 0x1cfcd(%rip), %rdi     # 0x36fb0
callq 0x19d00
movq -0xf8(%rbp), %rdi
callq 0x17420
jmp 0x1a367
movq 0x1cfc8(%rip), %rax     # 0x36fc8
movl $0x0, (%rax)
movq -0xf8(%rbp), %rdi
movb $0x0, -0x25(%rbp)
callq 0x5fd0
movl -0x14(%rbp), %edi
movq -0x20(%rbp), %rsi
leaq 0x9c0c(%rip), %rdx      # 0x23c30
leaq 0x1cbb5(%rip), %rcx     # 0x36be0
xorl %eax, %eax
movl %eax, %r8d
callq 0x4830
movl %eax, -0x24(%rbp)
cmpl $-0x1, -0x24(%rbp)
jne 0x1a04a
movl $0x3, -0x2c(%rbp)
jmp 0x1a0db
movq -0xe8(%rbp), %rsi
movl -0x14(%rbp), %edx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
leaq -0x58(%rbp), %rdi
callq 0x194a0
jmp 0x1a067
movq -0xf8(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movq %rsi, -0x108(%rbp)
callq 0x60a0
movq -0x108(%rbp), %rdi
callq 0x60e0
movq -0xf8(%rbp), %rdi
callq 0x16ee0
movb %al, -0xf9(%rbp)
jmp 0x1a09e
movb -0xf9(%rbp), %al
testb $0x1, %al
jne 0x1a0d4
jmp 0x1a0aa
movb $0x1, -0x25(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0x1a0db
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x60e0
jmp 0x1a377
movl $0x0, -0x2c(%rbp)
testb $0x1, -0x25(%rbp)
jne 0x1a0ed
movq -0xf8(%rbp), %rdi
callq 0x60e0
movl -0x2c(%rbp), %eax
movl %eax, -0x10c(%rbp)
testl %eax, %eax
je 0x1a10f
jmp 0x1a0fc
movl -0x10c(%rbp), %eax
subl $0x1, %eax
je 0x1a367
jmp 0x1a10d
jmp 0x1a114
jmp 0x1a006
movl -0x14(%rbp), %eax
movq 0x1cea2(%rip), %rcx     # 0x36fc0
cmpl (%rcx), %eax
jne 0x1a1be
leaq -0x89(%rbp), %rdi
movq %rdi, -0x118(%rbp)
callq 0x48a0
movq -0x118(%rbp), %rdx
leaq 0x9cfd(%rip), %rsi      # 0x23e44
leaq -0x88(%rbp), %rdi
callq 0x7620
jmp 0x1a155
movq -0xf8(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x17490
jmp 0x1a16a
leaq -0x88(%rbp), %rdi
callq 0x4300
leaq -0x89(%rbp), %rdi
callq 0x45b0
jmp 0x1a367
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1a1ad
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x4300
leaq -0x89(%rbp), %rdi
callq 0x45b0
jmp 0x1a377
movl -0x14(%rbp), %eax
movq 0x1cdf8(%rip), %rcx     # 0x36fc0
movl (%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1a26d
leaq -0xb1(%rbp), %rdi
movq %rdi, -0x120(%rbp)
callq 0x48a0
movq -0x120(%rbp), %rdx
leaq 0x9c5a(%rip), %rsi      # 0x23e50
leaq -0xb0(%rbp), %rdi
callq 0x7620
jmp 0x1a204
movq -0xf8(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x17490
jmp 0x1a219
leaq -0xb0(%rbp), %rdi
callq 0x4300
leaq -0xb1(%rbp), %rdi
callq 0x45b0
jmp 0x1a367
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1a25c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x4300
leaq -0xb1(%rbp), %rdi
callq 0x45b0
jmp 0x1a377
movq -0x20(%rbp), %rax
movq 0x1cd48(%rip), %rcx     # 0x36fc0
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x130(%rbp)
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x48a0
movq -0x130(%rbp), %rsi
movq -0x128(%rbp), %rdx
leaq -0xd8(%rbp), %rdi
callq 0x7620
jmp 0x1a2b5
movq -0xe8(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x19d30
movl %eax, -0x134(%rbp)
jmp 0x1a2d0
movq -0xe8(%rbp), %rax
movl -0x134(%rbp), %ecx
movl %ecx, (%rax)
leaq -0xd8(%rbp), %rdi
callq 0x4300
leaq -0xd9(%rbp), %rdi
callq 0x45b0
movq -0xe8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x1ccb7(%rip), %rcx     # 0x36fc0
movl (%rcx), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rsi
addq $0x8, %rdi
callq 0x46d0
movq -0xf8(%rbp), %rdi
movq -0xe8(%rbp), %rsi
callq 0x1a380
jmp 0x1a367
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1a359
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x4300
leaq -0xd9(%rbp), %rdi
callq 0x45b0
jmp 0x1a377
movq -0xf0(%rbp), %rax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x4890