// File: /workspace/github_cpp_makefile_star2_O2/occivink[P]pyct/pyct.cpp
// Function: parse_args(int, char**)
Args parse_args(int argc, char** argv) {
    argc--;
    argv++;
    Args args;
    if (argc == 0)
        throw invalid_argument{"Missing operation"};
    string op(argv[0]);
    if (op == "-h" or op == "--help") {
        args.help = true;
        return args;
    }
    const auto is_prefix = [](const string& pre, const string& s) {
        return pre.size() <= s.size() and equal(pre.begin(), pre.end(), s.begin());
    };
    if (is_prefix(op, "encrypt"))
        args.operation = Args::Operation::Encrypt;
    else if (is_prefix(op, "decrypt"))
        args.operation = Args::Operation::Decrypt;
    else if (is_prefix(op, "hash"))
        args.operation = Args::Operation::Hash;
    else
        throw invalid_argument{"Invalid operation"};

    auto option_value = [argc, argv](int i) {
        if (i >= argc)
            throw invalid_argument{"Missing option value"};
        return string(argv[i]);
    };
    for (int i = 1; i < argc; ++i) {
        string arg(argv[i]);
        if (arg == "-h" or arg == "--help") {
            args.help = true;
        } else if (arg == "-b" or arg == "--base-64") {
            args.base64 = true;
        } else if (arg == "--non-interactive") {
            args.interactive = false;
        } else if (arg == "--no-confirm") {
            args.confirm = false;
        } else if (arg == "--iterations") {
            args.iterations = stoi(option_value(++i));
        } else if (arg == "--work-area-size") {
            args.work_area_size = size_to_number(option_value(++i));
        } else if (arg == "--hash-fd") {
            auto fd = stoi(option_value(++i));
            vector<u8> hash;
            try {
                hash = from_base_64(read_from_fd<string>(fd));
            } catch(...) {
                throw invalid_argument{"Invalid hash"};
            }
            if (hash.size() != 32)
                throw invalid_argument{"Hash is not the correct size"};
            args.hash.emplace();
            copy(hash.begin(), hash.end(), args.hash->begin());
        } else if (arg == "--pass-fd") {
            auto fd = stoi(option_value(++i));
            args.password = read_from_fd<string>(fd);
        } else if (arg == "--input-data-fd") {
            auto fd = stoi(option_value(++i));
            args.input_data_fd = fd;
        } else if (arg == "-s" or arg == "--salt") {
            args.salt = option_value(++i);
            if (args.salt->size() < 8)
                throw invalid_argument{"Salt is too small"};
        } else if (arg == "-l" or arg == "--padded-length") {
            args.padded_length = size_to_number(option_value(++i));
        } else {
            throw invalid_argument{"Unrecognized argument: " + arg};
        }
    }
    if (args.hash and args.password)
        throw invalid_argument{"Can only provide one of hash and password at once"};
    else if (args.operation != Args::Operation::Encrypt and args.padded_length)
        throw invalid_argument{"Can only pad when encrypting"};
    return args;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rdx, %r14
movl %esi, %ebp
movq %rdi, %rbx
callq 0xae90
decl %ebp
movl %ebp, 0x3c(%rsp)
je 0xa34e
addq $0x8, %r14
movq (%r14), %rsi
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0xaeb4
leaq 0x3395(%rip), %rsi      # 0xd177
leaq 0x80(%rsp), %rdi
callq 0xaeef
testb %al, %al
jne 0x9e0b
leaq 0x3380(%rip), %rsi      # 0xd17a
leaq 0x80(%rsp), %rdi
callq 0xaeef
testb %al, %al
je 0x9e31
movb $0x1, 0x4(%rbx)
leaq 0x80(%rsp), %rdi
callq 0x20e0
movq %rbx, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3349(%rip), %rsi      # 0xd181
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rdx
movq %rbx, (%rsp)
callq 0xaeb4
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xa602
movl %eax, %r12d
leaq 0x50(%rsp), %rdi
callq 0x20e0
xorl %eax, %eax
pushq $0x1
popq %r15
testb %r12b, %r12b
jne 0x9ef3
leaq 0x330d(%rip), %rsi      # 0xd189
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0xaeb4
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xa602
movl %eax, %r12d
leaq 0x50(%rsp), %rdi
callq 0x20e0
movl %r15d, %eax
testb %r12b, %r12b
jne 0x9ef3
leaq 0x3346(%rip), %rsi      # 0xd1ff
leaq 0x50(%rsp), %rdi
leaq 0x10(%rsp), %rdx
callq 0xaeb4
leaq 0x80(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xa602
movl %eax, %r12d
leaq 0x50(%rsp), %rdi
callq 0x20e0
testb %r12b, %r12b
je 0xa3b7
pushq $0x2
popq %rax
movl %eax, (%rbx)
leaq 0x40(%rsp), %rax
movl 0x3c(%rsp), %ecx
movl %ecx, (%rax)
movq %r14, 0x8(%rax)
leaq 0x80(%rbx), %rax
movq %rax, 0x70(%rsp)
leaq 0x30(%rbx), %rax
movq %rax, 0x78(%rsp)
leaq 0x58(%rbx), %r12
leaq 0x50(%rsp), %r13
leaq 0xa0(%rsp), %rbx
leaq 0xc0(%rsp), %rbp
cmpl 0x3c(%rsp), %r15d
jge 0xa30c
movslq %r15d, %rax
movq (%r14,%rax,8), %rsi
movq %r13, %rdi
leaq 0x10(%rsp), %rdx
callq 0xaeb4
movq %r13, %rdi
leaq 0x321c(%rip), %rsi      # 0xd177
callq 0xaeef
testb %al, %al
jne 0x9f77
movq %r13, %rdi
leaq 0x320c(%rip), %rsi      # 0xd17a
callq 0xaeef
testb %al, %al
je 0x9f8c
movq (%rsp), %rax
movb $0x1, 0x4(%rax)
movq %r13, %rdi
callq 0x20e0
incl %r15d
jmp 0x9f32
movq %r13, %rdi
leaq 0x320d(%rip), %rsi      # 0xd1a3
callq 0xaeef
testb %al, %al
jne 0x9fb2
movq %r13, %rdi
leaq 0x31fd(%rip), %rsi      # 0xd1a6
callq 0xaeef
testb %al, %al
je 0x9fbc
movq (%rsp), %rax
movb $0x1, 0x5(%rax)
jmp 0x9f7f
movq %r13, %rdi
leaq 0x31ea(%rip), %rsi      # 0xd1b0
callq 0xaeef
testb %al, %al
je 0x9fd9
movq (%rsp), %rax
movb $0x0, 0x6(%rax)
jmp 0x9f7f
movq %r13, %rdi
leaq 0x31df(%rip), %rsi      # 0xd1c2
callq 0xaeef
testb %al, %al
je 0x9ff6
movq (%rsp), %rax
movb $0x0, 0x7(%rax)
jmp 0x9f7f
movq %r13, %rdi
leaq 0x31cf(%rip), %rsi      # 0xd1cf
callq 0xaeef
testb %al, %al
je 0xa043
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0xaefc
movq (%rsp), %rcx
cmpb $0x0, 0x18(%rcx)
jne 0xa03b
movb $0x1, 0x18(%rcx)
cltq
movq %rax, 0x10(%rcx)
jmp 0xa081
movq %r13, %rdi
leaq 0x318f(%rip), %rsi      # 0xd1dc
callq 0xaeef
testb %al, %al
je 0xa090
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
callq 0x916c
movq (%rsp), %rcx
movq %rax, 0x20(%rcx)
movb $0x1, 0x28(%rcx)
leaq 0x10(%rsp), %rdi
callq 0x20e0
jmp 0x9f7f
movq %r13, %rdi
leaq 0x3153(%rip), %rsi      # 0xd1ed
callq 0xaeef
testb %al, %al
je 0xa185
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0xaefc
movl %eax, 0xc(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x20e0
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
movq %rbx, %rdi
movl 0xc(%rsp), %esi
callq 0xaf18
movq %rbp, %rdi
leaq 0xa0(%rsp), %rsi
callq 0x93db
leaq 0x10(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
callq 0xba42
leaq 0xc0(%rsp), %rdi
callq 0xb73e
leaq 0xa0(%rsp), %rdi
callq 0x20e0
movq 0x10(%rsp), %rax
movq 0x18(%rsp), %rcx
movq %rcx, %rdx
subq %rax, %rdx
cmpq $0x20, %rdx
jne 0xa3ec
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%r12)
movups %xmm0, (%r12)
movq (%rsp), %rsi
movb $0x1, 0x78(%rsi)
cmpq %rax, %rcx
je 0xa176
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%r12)
movups %xmm0, (%r12)
leaq 0x10(%rsp), %rdi
callq 0xb73e
jmp 0x9f7f
movq %r13, %rdi
leaq 0x3092(%rip), %rsi      # 0xd221
callq 0xaeef
testb %al, %al
je 0xa1ec
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0xaefc
movl %eax, 0xc(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x20e0
leaq 0x10(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0xaf18
movq 0x78(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xb00a
jmp 0xa081
movq %r13, %rdi
leaq 0x3035(%rip), %rsi      # 0xd22b
callq 0xaeef
testb %al, %al
je 0xa241
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0xaefc
movl %eax, 0xc(%rsp)
leaq 0x10(%rsp), %rdi
callq 0x20e0
movq (%rsp), %rax
movl 0xc(%rsp), %ecx
movl %ecx, 0x8(%rax)
jmp 0x9f7f
movq %r13, %rdi
leaq 0x2ff0(%rip), %rsi      # 0xd23b
callq 0xaeef
testb %al, %al
jne 0xa267
movq %r13, %rdi
leaq 0x2fe0(%rip), %rsi      # 0xd23e
callq 0xaeef
testb %al, %al
je 0xa2ac
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
movq 0x70(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0xb00a
leaq 0x10(%rsp), %rdi
callq 0x20e0
movq (%rsp), %rax
cmpq $0x7, 0x88(%rax)
ja 0x9f7f
jmp 0xa421
movq %r13, %rdi
leaq 0x2fa1(%rip), %rsi      # 0xd257
callq 0xaeef
testb %al, %al
jne 0xa2d6
movq %r13, %rdi
leaq 0x2f91(%rip), %rsi      # 0xd25a
callq 0xaeef
testb %al, %al
je 0xa456
incl %r15d
leaq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movl %r15d, %edx
callq 0xa620
leaq 0x10(%rsp), %rdi
callq 0x916c
movq (%rsp), %rcx
movq %rax, 0xa8(%rcx)
movb $0x1, 0xb0(%rcx)
jmp 0xa081
movq (%rsp), %rbx
cmpb $0x0, 0x78(%rbx)
je 0xa31c
cmpb $0x1, 0x50(%rbx)
je 0xa387
cmpl $0x0, (%rbx)
je 0x9e0f
cmpb $0x1, 0xb0(%rbx)
jne 0x9e0f
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2f70(%rip), %rsi      # 0xd2b4
movq %rax, %rdi
callq 0x23a0
jmp 0xa3a1
movq %rbx, (%rsp)
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2e01(%rip), %rsi      # 0xd165
movq %rax, %rdi
callq 0x23a0
movq 0x7c5d(%rip), %rsi      # 0x11fd0
movq 0x7c46(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
jmp 0xa559
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2ee9(%rip), %rsi      # 0xd282
movq %rax, %rdi
callq 0x23a0
movq 0x7c28(%rip), %rsi      # 0x11fd0
movq 0x7c11(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2dc8(%rip), %rsi      # 0xd191
movq %rax, %rdi
callq 0x23a0
movq 0x7bf8(%rip), %rsi      # 0x11fd0
movq 0x7be1(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
jmp 0xa559
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2e06(%rip), %rsi      # 0xd204
movq %rax, %rdi
callq 0x23a0
movq 0x7bc3(%rip), %rsi      # 0x11fd0
movq 0x7bac(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
jmp 0xa559
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2e12(%rip), %rsi      # 0xd245
movq %rax, %rdi
callq 0x23a0
movq 0x7b8e(%rip), %rsi      # 0x11fd0
movq 0x7b77(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
jmp 0xa559
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2e02(%rip), %rsi      # 0xd26a
leaq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rdx
callq 0xb02b
movb $0x1, %bpl
leaq 0x10(%rsp), %rsi
movq %r15, %rdi
callq 0x2370
xorl %ebp, %ebp
movq 0x7b40(%rip), %rsi      # 0x11fd0
movq 0x7b29(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
jmp 0xa559
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x20e0
testb %bpl, %bpl
jne 0xa4cf
jmp 0xa5bb
jmp 0xa4cc
jmp 0xa58e
jmp 0xa5b8
jmp 0xa5b8
movq %rax, %r14
movq %r15, %rdi
callq 0x2160
jmp 0xa5bb
jmp 0xa5b8
jmp 0xa58e
jmp 0xa5b8
movq %rax, %r14
jmp 0xa56e
movq %rax, %r14
movq %r15, %rdi
callq 0x2160
jmp 0xa56e
jmp 0xa5b8
jmp 0xa58e
jmp 0xa5b8
movq %rax, %r14
leaq 0xa0(%rsp), %rdi
callq 0x20e0
jmp 0xa521
movq %rax, %r14
movq %r14, %rdi
callq 0x20a0
pushq $0x10
popq %rdi
callq 0x2100
movq %rax, %r15
leaq 0x2cbc(%rip), %rsi      # 0xd1f7
movq %rax, %rdi
callq 0x23a0
movq 0x7a86(%rip), %rsi      # 0x11fd0
movq 0x7a6f(%rip), %rdx      # 0x11fc0
movq %r15, %rdi
callq 0x2360
movq %rax, %r14
jmp 0xa569
movq %rax, %r14
movq %r15, %rdi
callq 0x2160
callq 0x2340
leaq 0x10(%rsp), %rdi
callq 0xb73e
jmp 0xa5bb
movq %rax, %rdi
callq 0xafff
jmp 0xa58e
jmp 0xa5b8
jmp 0xa58e
jmp 0xa5b8
jmp 0xa5e1
jmp 0xa5a5
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x20e0
jmp 0xa5bb
jmp 0xa5b8
jmp 0xa5a5
jmp 0xa5b8
jmp 0xa5e1
movq %rax, %r14
movq %r15, %rdi
callq 0x2160
jmp 0xa5e4
jmp 0xa5b8
jmp 0xa5e1
jmp 0xa5e1
movq %rax, %r14
leaq 0x50(%rsp), %rdi
callq 0x20e0
jmp 0xa5e4
jmp 0xa5e1
jmp 0xa5dc
movq %rax, %r14
movq %r15, %rdi
callq 0x2160
jmp 0xa5f1
movq %rbx, (%rsp)
movq %rax, %r14
jmp 0xa5f1
movq %rax, %r14
leaq 0x80(%rsp), %rdi
callq 0x20e0
movq (%rsp), %rdi
callq 0xb0a2
movq %r14, %rdi
callq 0x2380