| 13694 | TOML_NODISCARD |
| 13695 | TOML_NEVER_INLINE |
| 13696 | std::string_view parse_literal_string(bool multi_line) |
| 13697 | { |
| 13698 | return_if_error({}); |
| 13699 | assert_not_eof(); |
| 13700 | TOML_ASSERT_ASSUME(*cp == U'\''); |
| 13701 | push_parse_scope("literal string"sv); |
| 13702 | |
| 13703 | // skip the delimiter |
| 13704 | advance_and_return_if_error_or_eof({}); |
| 13705 | |
| 13706 | // multi-line strings ignore a single line ending right at the beginning |
| 13707 | if (multi_line) |
| 13708 | { |
| 13709 | consume_line_break(); |
| 13710 | return_if_error({}); |
| 13711 | set_error_and_return_if_eof({}); |
| 13712 | } |
| 13713 | |
| 13714 | auto& str = string_buffer; |
| 13715 | str.clear(); |
| 13716 | do |
| 13717 | { |
| 13718 | return_if_error({}); |
| 13719 | |
| 13720 | // handle closing delimiters |
| 13721 | if (*cp == U'\'') |
| 13722 | { |
| 13723 | if (multi_line) |
| 13724 | { |
| 13725 | size_t lookaheads = {}; |
| 13726 | size_t consecutive_delimiters = 1; |
| 13727 | do |
| 13728 | { |
| 13729 | advance_and_return_if_error({}); |
| 13730 | lookaheads++; |
| 13731 | if (!is_eof() && *cp == U'\'') |
| 13732 | consecutive_delimiters++; |
| 13733 | else |
| 13734 | break; |
| 13735 | } |
| 13736 | while (lookaheads < 4u); |
| 13737 | |
| 13738 | switch (consecutive_delimiters) |
| 13739 | { |
| 13740 | // ''' ' (one quote somewhere in a ML string) |
| 13741 | case 1: str += '\''; continue; |
| 13742 | |
| 13743 | // ''' '' (two quotes somewhere in a ML string) |
| 13744 | case 2: str.append("''"sv); continue; |
| 13745 | |
| 13746 | // ''' ''' (the end of the string) |
| 13747 | case 3: return str; |
| 13748 | |
| 13749 | // ''' '''' (one at the end of the string) |
| 13750 | case 4: str += '\''; return str; |
| 13751 | |
| 13752 | // ''' ''''' (two quotes at the end of the string) |
| 13753 | case 5: |
nothing calls this directly
no test coverage detected