// File: sbingner[P]kerneldec/lzfse/src/lzfse_main.c
// Function: main
int main(int argc, char **argv) {
  const char *in_file = 0;  // stdin
  const char *out_file = 0; // stdout
  int op = -1;              // invalid op
  int verbosity = 0;        // quiet

  // Parse options
  for (int i = 1; i < argc;) {
    // no args
    const char *a = argv[i++];
    if (strcmp(a, "-h") == 0)
      USAGE(argc, argv);
    if (strcmp(a, "-v") == 0) {
      verbosity++;
      continue;
    }
    if (strcmp(a, "-encode") == 0) {
      op = LZFSE_ENCODE;
      continue;
    }
    if (strcmp(a, "-decode") == 0) {
      op = LZFSE_DECODE;
      continue;
    }

    // one arg
    const char **arg_var = 0;
    if (strcmp(a, "-i") == 0 && in_file == 0)
      arg_var = &in_file;
    else if (strcmp(a, "-o") == 0 && out_file == 0)
      arg_var = &out_file;
    if (arg_var != 0) {
      // Flag is recognized. Check if there is an argument.
      if (i == argc)
        USAGE_MSG(argc, argv, "Error: Missing arg after %s\n", a);
      *arg_var = argv[i++];
      continue;
    }

    USAGE_MSG(argc, argv, "Error: invalid flag %s\n", a);
  }
  if (op < 0)
    USAGE_MSG(argc, argv, "Error: -encode|-decode required\n");

  // Info
  if (verbosity > 0) {
    if (op == LZFSE_ENCODE)
      fprintf(stderr, "LZFSE encode\n");
    if (op == LZFSE_DECODE)
      fprintf(stderr, "LZFSE decode\n");
    fprintf(stderr, "Input: %s\n", in_file ? in_file : "stdin");
    fprintf(stderr, "Output: %s\n", out_file ? out_file : "stdout");
  }

  // Load input
  size_t out_size = 0;     // used in OUT
  int in_fd = -1;          // input file desc

  if (in_file != 0) {
    // If we have a file name, open it, and allocate the exact input size
    struct stat st;
#if defined(_WIN32)
    in_fd = open(in_file, O_RDONLY | O_BINARY);
#else
    in_fd = open(in_file, O_RDONLY);
#endif
    if (in_fd < 0) {
      perror(in_file);
      exit(1);
    }
  } else {
    in_fd = 0;
#if defined(_WIN32)
    if (setmode(in_fd, O_BINARY) == -1) {
      perror("setmode");
      exit(1);
    }
#endif
  }

  int out_fd = -1;
  if (out_file) {
#if defined(_WIN32)
    out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
      S_IWRITE);
#else
    out_fd = open(out_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
#endif
    if (out_fd < 0) {
      perror(out_file);
      exit(1);
    }
  } else {
    out_fd = 1; // stdout
#if defined(_WIN32)
    if (setmode(out_fd, O_BINARY) == -1) {
      perror("setmode");
      exit(1);
    }
#endif
  }
  //  Encode/decode
  //  Compute size for result buffer; we assume here that encode shrinks size,
  //  and that decode grows by no more than 4x.  These are reasonable common-
  //  case guidelines, but are not formally guaranteed to be satisfied.

  double c0 = get_time();
  if (op == LZFSE_ENCODE) {
      fprintf(stderr, "encode not implemented yet\n");
      exit(1);
  } else {
      FILE *outfile = fdopen(out_fd, "w");
      FILE *infile = fdopen(in_fd, "r");
      int error;
      out_size = lzfse_decode_file(outfile, infile, 0, &error, NULL);
      fclose(infile);
      fclose(outfile);
  }

  double c1 = get_time();

  if (out_file != 0) {
    close(out_fd);
    out_fd = -1;
  }

  return 0; // OK
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movl $0xffffffff, -0x24(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x345d
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), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
leaq 0xbd67(%rip), %rsi      # 0xf056
callq 0x30a0
cmpl $0x0, %eax
jne 0x330e
jmp 0x32fb
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x3240
xorl %edi, %edi
callq 0x3120
movq -0x38(%rbp), %rdi
leaq 0xbd40(%rip), %rsi      # 0xf059
callq 0x30a0
cmpl $0x0, %eax
jne 0x332e
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x32be
movq -0x38(%rbp), %rdi
leaq 0xbd23(%rip), %rsi      # 0xf05c
callq 0x30a0
cmpl $0x0, %eax
jne 0x334f
movl $0x0, -0x24(%rbp)
jmp 0x32be
movq -0x38(%rbp), %rdi
leaq 0xbd0a(%rip), %rsi      # 0xf064
callq 0x30a0
cmpl $0x0, %eax
jne 0x3370
movl $0x1, -0x24(%rbp)
jmp 0x32be
movq $0x0, -0x40(%rbp)
movq -0x38(%rbp), %rdi
leaq 0xbce9(%rip), %rsi      # 0xf06c
callq 0x30a0
cmpl $0x0, %eax
jne 0x339e
cmpq $0x0, -0x18(%rbp)
jne 0x339e
leaq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x33c4
movq -0x38(%rbp), %rdi
leaq 0xbcc6(%rip), %rsi      # 0xf06f
callq 0x30a0
cmpl $0x0, %eax
jne 0x33c2
cmpq $0x0, -0x20(%rbp)
jne 0x33c2
leaq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
jmp 0x33c4
cmpq $0x0, -0x40(%rbp)
je 0x3429
movl -0x2c(%rbp), %eax
cmpl -0x8(%rbp), %eax
jne 0x3407
jmp 0x33d5
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x3240
movq 0xfc10(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
movq -0x38(%rbp), %rdx
leaq 0xbc7c(%rip), %rsi      # 0xf072
movb $0x0, %al
callq 0x30b0
movl $0x1, %edi
callq 0x3120
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), %rcx
movq -0x40(%rbp), %rax
movq %rcx, (%rax)
jmp 0x32be
jmp 0x342b
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x3240
movq 0xfbba(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
movq -0x38(%rbp), %rdx
leaq 0xbc43(%rip), %rsi      # 0xf08f
movb $0x0, %al
callq 0x30b0
movl $0x1, %edi
callq 0x3120
cmpl $0x0, -0x24(%rbp)
jge 0x3493
jmp 0x3465
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x3240
movq 0xfb80(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0xbc25(%rip), %rsi      # 0xf0a7
movb $0x0, %al
callq 0x30b0
movl $0x1, %edi
callq 0x3120
cmpl $0x0, -0x28(%rbp)
jle 0x357b
cmpl $0x0, -0x24(%rbp)
jne 0x34bb
movq 0xfb4e(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0xbc14(%rip), %rsi      # 0xf0c8
movb $0x0, %al
callq 0x30b0
cmpl $0x1, -0x24(%rbp)
jne 0x34d9
movq 0xfb30(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0xbc04(%rip), %rsi      # 0xf0d6
movb $0x0, %al
callq 0x30b0
movq 0xfb18(%rip), %rax      # 0x12ff8
movq (%rax), %rax
movq %rax, -0x118(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x34fe
movq -0x18(%rbp), %rax
movq %rax, -0x120(%rbp)
jmp 0x350e
leaq 0xbbea(%rip), %rax      # 0xf0ef
movq %rax, -0x120(%rbp)
jmp 0x350e
movq -0x118(%rbp), %rdi
movq -0x120(%rbp), %rdx
leaq 0xbbc1(%rip), %rsi      # 0xf0e4
movb $0x0, %al
callq 0x30b0
movq 0xfac7(%rip), %rax      # 0x12ff8
movq (%rax), %rax
movq %rax, -0x128(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x354f
movq -0x20(%rbp), %rax
movq %rax, -0x130(%rbp)
jmp 0x355f
leaq 0xbbab(%rip), %rax      # 0xf101
movq %rax, -0x130(%rbp)
jmp 0x355f
movq -0x128(%rbp), %rdi
movq -0x130(%rbp), %rdx
leaq 0xbb81(%rip), %rsi      # 0xf0f5
movb $0x0, %al
callq 0x30b0
movq $0x0, -0x48(%rbp)
movl $0xffffffff, -0x4c(%rbp) # imm = 0xFFFFFFFF
cmpq $0x0, -0x18(%rbp)
je 0x35bc
movq -0x18(%rbp), %rdi
xorl %esi, %esi
movb $0x0, %al
callq 0x3100
movl %eax, -0x4c(%rbp)
cmpl $0x0, -0x4c(%rbp)
jge 0x35ba
movq -0x18(%rbp), %rdi
callq 0x3110
movl $0x1, %edi
callq 0x3120
jmp 0x35c3
movl $0x0, -0x4c(%rbp)
movl $0xffffffff, -0xe4(%rbp) # imm = 0xFFFFFFFF
cmpq $0x0, -0x20(%rbp)
je 0x360d
movq -0x20(%rbp), %rdi
movl $0x241, %esi            # imm = 0x241
movl $0x1a4, %edx            # imm = 0x1A4
movb $0x0, %al
callq 0x3100
movl %eax, -0xe4(%rbp)
cmpl $0x0, -0xe4(%rbp)
jge 0x360b
movq -0x20(%rbp), %rdi
callq 0x3110
movl $0x1, %edi
callq 0x3120
jmp 0x3617
movl $0x1, -0xe4(%rbp)
callq 0x36f0
movsd %xmm0, -0xf0(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x364c
movq 0xf9c7(%rip), %rax      # 0x12ff8
movq (%rax), %rdi
leaq 0xbacd(%rip), %rsi      # 0xf108
movb $0x0, %al
callq 0x30b0
movl $0x1, %edi
callq 0x3120
movl -0xe4(%rbp), %edi
leaq 0xbacb(%rip), %rsi      # 0xf124
callq 0x30e0
movq %rax, -0xf8(%rbp)
movl -0x4c(%rbp), %edi
leaq 0xbab7(%rip), %rsi      # 0xf126
callq 0x30e0
movq %rax, -0x100(%rbp)
movq -0xf8(%rbp), %rdi
movq -0x100(%rbp), %rsi
xorl %eax, %eax
movl %eax, %r8d
leaq -0x104(%rbp), %rcx
movq %r8, %rdx
callq 0x4250
movq %rax, -0x48(%rbp)
movq -0x100(%rbp), %rdi
callq 0x3050
movq -0xf8(%rbp), %rdi
callq 0x3050
callq 0x36f0
movsd %xmm0, -0x110(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x36e2
movl -0xe4(%rbp), %edi
callq 0x3090
movl $0xffffffff, -0xe4(%rbp) # imm = 0xFFFFFFFF
xorl %eax, %eax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
nopl (%rax)