// File: ridiculousfish[P]docopt_fish/docopt_fish.cpp
// Function: docopt_fish::parse_one_option_spec(docopt_fish::rstring_t const&, std::map<docopt_fish::rstring_t, docopt_fish::base_metadata_t<docopt_fish::rstring_t>, std::less<docopt_fish::rstring_t>, std::allocator<std::pair<docopt_fish::rstring_t const, docopt_fish::base_metadata_t<docopt_fish::rstring_t>>>>*, std::vector<docopt_fish::error_t, std::allocator<docopt_fish::error_t>>*)
static option_t parse_one_option_spec(const rstring_t &spec, metadata_map_t *metadata,
                                      error_list_t *errors) {
    assert(!spec.empty() && spec[0] == '-');
    const size_t end = spec.length();
    option_t result;

    // Look for two spaces. Those separate the description.
    size_t options_end = spec.find("  ");
    if (options_end > end) {
        options_end = end;  // no description
    }

    // Determine the description range (possibly empty). Trim leading and trailing
    // whitespace
    rstring_t description = spec.substr_from(options_end).trim_whitespace();

    // Parse out a "default:" value.
    if (!description.empty()) {
        // TODO: handle the case where there's more than one
        const char *default_prefix = "[default:";
        size_t default_prefix_loc = description.find_case_insensitive(default_prefix);
        if (default_prefix_loc != rstring_t::npos) {
            rstring_t default_value =
                description.substr_from(default_prefix_loc + strlen(default_prefix))
                    .trim_whitespace();

            // Find the closing ']'
            size_t default_value_end = default_value.find("]");
            if (default_value_end == rstring_t::npos) {
                append_token_error(errors, default_value, error_missing_close_bracket_in_default,
                                    "Missing ']' to match opening '['");
            } else {
                result.default_value = default_value.substr(0, default_value_end);
            }
        }
    }

    // Parse the options portion
    // This looks like '-f, --foo'
    rstring_t remaining = spec.substr(0, options_end).trim_whitespace();
    while (!remaining.empty()) {
        if (remaining[0] != '-') {
            append_token_error(errors, remaining, error_invalid_option_name, "Not an option");
            break;
        }

        option_t opt;
        if (!option_t::parse_from_string(&remaining, &opt, errors)) {
            // Failed to get an option, give up
            break;
        }
        result.merge_from(opt);

        // Skip over commas, which separate arguments
        remaining.scan_multiple<char_is_space, it_equals<','>, char_is_space>();
    }

    // Store any description in the metadata
    if (!description.empty()) {
        for (const rstring_t &name : result.names) {
            if (!name.empty()) {
                (*metadata)[name].description = description;
            }
        }
    }

    return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x1e8(%rbp)
movq %rdi, -0x1e0(%rbp)
movq %rsi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
callq 0xbe30
movb %al, %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0x1d1(%rbp)
jne 0xb426
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x110a0
cmpl $0x2d, %eax
sete %al
movb %al, -0x1d1(%rbp)
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0xb432
jmp 0xb434
jmp 0xb453
leaq 0x408c8(%rip), %rdi     # 0x4bd03
leaq 0x3fc46(%rip), %rsi     # 0x4b088
movl $0x108, %edx            # imm = 0x108
leaq 0x408d5(%rip), %rcx     # 0x4bd23
callq 0x81e0
movq -0x8(%rbp), %rdi
callq 0xbf20
movq -0x1e8(%rbp), %rdi
movq %rax, -0x20(%rbp)
callq 0x1d030
movq -0x8(%rbp), %rdi
leaq 0x4090d(%rip), %rsi     # 0x4bd84
callq 0x1d080
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
jbe 0xb492
movq -0x20(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rsi
movq -0x28(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0xc5d0
leaq -0x40(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x1bab0
leaq -0x40(%rbp), %rdi
callq 0xbe30
testb $0x1, %al
jne 0xb5a9
leaq 0x408bf(%rip), %rax     # 0x4bd87
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x1bbb0
movq %rax, -0x68(%rbp)
cmpq $-0x1, -0x68(%rbp)
je 0xb5a7
movq -0x68(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x60(%rbp), %rdi
callq 0x8110
movq -0x1f0(%rbp), %rdx
addq %rax, %rdx
leaq -0x98(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xc5d0
leaq -0x80(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x1bab0
leaq -0x80(%rbp), %rdi
leaq 0x41e5b(%rip), %rsi     # 0x4d38c
callq 0x1d080
movq %rax, -0xa0(%rbp)
cmpq $-0x1, -0xa0(%rbp)
jne 0xb562
movq -0x18(%rbp), %rdi
leaq -0x80(%rbp), %rsi
movl $0xa, %edx
leaq 0x40836(%rip), %rcx     # 0x4bd91
callq 0x8e80
jmp 0xb5a5
movq -0xa0(%rbp), %rcx
leaq -0xb8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0xc520
movq -0x1e8(%rbp), %rax
movq -0xb8(%rbp), %rcx
movq %rcx, 0x60(%rax)
movq -0xb0(%rbp), %rcx
movq %rcx, 0x68(%rax)
movq -0xa8(%rbp), %rcx
movq %rcx, 0x70(%rax)
jmp 0xb5a7
jmp 0xb5a9
movq -0x8(%rbp), %rsi
movq -0x28(%rbp), %rcx
leaq -0xe8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0xc520
leaq -0xd0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x1bab0
leaq -0xd0(%rbp), %rdi
callq 0xbe30
xorb $-0x1, %al
testb $0x1, %al
jne 0xb5eb
jmp 0xb672
leaq -0xd0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x110a0
cmpl $0x2d, %eax
je 0xb61e
movq -0x18(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
movl $0x5, %edx
leaq 0x4079b(%rip), %rcx     # 0x4bdb2
callq 0x8e80
jmp 0xb672
leaq -0x168(%rbp), %rdi
callq 0x1d030
movq -0x18(%rbp), %rdx
leaq -0xd0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x8950
testb $0x1, %al
jne 0xb647
jmp 0xb672
movq -0x1e8(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x1d0b0
leaq -0x1b0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x1d150
jmp 0xb5d4
leaq -0x40(%rbp), %rdi
callq 0xbe30
testb $0x1, %al
jne 0xb725
movq -0x1e8(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rdi
callq 0x1d180
movq %rax, -0x1c0(%rbp)
movq -0x1b8(%rbp), %rdi
callq 0x1d1a0
movq %rax, -0x1c8(%rbp)
movq -0x1c0(%rbp), %rax
cmpq -0x1c8(%rbp), %rax
je 0xb723
movq -0x1c0(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x1d0(%rbp), %rdi
callq 0xbe30
testb $0x1, %al
jne 0xb70d
movq -0x10(%rbp), %rdi
movq -0x1d0(%rbp), %rsi
callq 0x1bc10
movq -0x40(%rbp), %rcx
movq %rcx, 0x30(%rax)
movq -0x38(%rbp), %rcx
movq %rcx, 0x38(%rax)
movq -0x30(%rbp), %rcx
movq %rcx, 0x40(%rax)
jmp 0xb70f
movq -0x1c0(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x1c0(%rbp)
jmp 0xb6b7
jmp 0xb725
movq -0x1e0(%rbp), %rax
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
nopw %cs:(%rax,%rax)