| 15147 | } |
| 15148 | |
| 15149 | TOML_NEVER_INLINE |
| 15150 | bool parse_key() |
| 15151 | { |
| 15152 | return_if_error({}); |
| 15153 | assert_not_eof(); |
| 15154 | TOML_ASSERT_ASSUME(is_bare_key_character(*cp) || is_string_delimiter(*cp)); |
| 15155 | push_parse_scope("key"sv); |
| 15156 | |
| 15157 | key_buffer.clear(); |
| 15158 | recording_whitespace = false; |
| 15159 | |
| 15160 | while (!is_error()) |
| 15161 | { |
| 15162 | std::string_view key_segment; |
| 15163 | const auto key_begin = current_position(); |
| 15164 | |
| 15165 | // bare_key_segment |
| 15166 | if (is_bare_key_character(*cp)) |
| 15167 | key_segment = parse_bare_key_segment(); |
| 15168 | |
| 15169 | // "quoted key segment" |
| 15170 | else if (is_string_delimiter(*cp)) |
| 15171 | { |
| 15172 | const auto begin_pos = cp->position; |
| 15173 | |
| 15174 | recording_whitespace = true; |
| 15175 | parsed_string str = parse_string(); |
| 15176 | recording_whitespace = false; |
| 15177 | return_if_error({}); |
| 15178 | |
| 15179 | if (str.was_multi_line) |
| 15180 | { |
| 15181 | set_error_at(begin_pos, |
| 15182 | "multi-line strings are prohibited in "sv, |
| 15183 | key_buffer.empty() ? ""sv : "dotted "sv, |
| 15184 | "keys"sv); |
| 15185 | return_after_error({}); |
| 15186 | } |
| 15187 | else |
| 15188 | key_segment = str.value; |
| 15189 | } |
| 15190 | |
| 15191 | // ??? |
| 15192 | else |
| 15193 | set_error_and_return_default("expected bare key starting character or string delimiter, saw '"sv, |
| 15194 | to_sv(*cp), |
| 15195 | "'"sv); |
| 15196 | |
| 15197 | const auto key_end = current_position(); |
| 15198 | |
| 15199 | // whitespace following the key segment |
| 15200 | consume_leading_whitespace(); |
| 15201 | |
| 15202 | // store segment |
| 15203 | key_buffer.push_back(key_segment, key_begin, key_end); |
| 15204 | |
| 15205 | // eof or no more key to come |
| 15206 | if (is_eof() || *cp != U'.') |