| 16144 | } |
| 16145 | |
| 16146 | TOML_EXTERNAL_LINKAGE |
| 16147 | void formatter::print_string(std::string_view str, bool allow_multi_line, bool allow_bare) |
| 16148 | { |
| 16149 | if (str.empty()) |
| 16150 | { |
| 16151 | print_unformatted(literal_strings_allowed() ? "''"sv : "\"\""sv); |
| 16152 | return; |
| 16153 | } |
| 16154 | |
| 16155 | // pre-scan the string to determine how we should output it |
| 16156 | formatted_string_traits traits = {}; |
| 16157 | |
| 16158 | if (!allow_bare) |
| 16159 | traits |= formatted_string_traits::non_bare; |
| 16160 | bool unicode_allowed = unicode_strings_allowed(); |
| 16161 | |
| 16162 | // ascii fast path |
| 16163 | if (is_ascii(str.data(), str.length())) |
| 16164 | { |
| 16165 | for (auto c : str) |
| 16166 | { |
| 16167 | switch (c) |
| 16168 | { |
| 16169 | case '\n': traits |= formatted_string_traits::line_breaks; break; |
| 16170 | case '\t': traits |= formatted_string_traits::tabs; break; |
| 16171 | case '\'': traits |= formatted_string_traits::single_quotes; break; |
| 16172 | default: |
| 16173 | { |
| 16174 | if TOML_UNLIKELY(is_control_character(c)) |
| 16175 | traits |= formatted_string_traits::control_chars; |
| 16176 | |
| 16177 | if (!is_ascii_bare_key_character(static_cast<char32_t>(c))) |
| 16178 | traits |= formatted_string_traits::non_bare; |
| 16179 | break; |
| 16180 | } |
| 16181 | } |
| 16182 | |
| 16183 | static constexpr auto all_ascii_traits = |
| 16184 | formatted_string_traits::all & ~formatted_string_traits::non_ascii; |
| 16185 | if (traits == all_ascii_traits) |
| 16186 | break; |
| 16187 | } |
| 16188 | } |
| 16189 | |
| 16190 | // unicode slow path |
| 16191 | else |
| 16192 | { |
| 16193 | traits |= formatted_string_traits::non_ascii; |
| 16194 | utf8_decoder decoder; |
| 16195 | |
| 16196 | // if the unicode is malformed just treat the string as a single-line non-literal and |
| 16197 | // escape all non-ascii characters (to ensure round-tripping and help with diagnostics) |
| 16198 | const auto bad_unicode = [&]() noexcept |
| 16199 | { |
| 16200 | traits &= ~formatted_string_traits::line_breaks; |
| 16201 | traits |= formatted_string_traits::control_chars | formatted_string_traits::non_bare; |
| 16202 | unicode_allowed = false; |
| 16203 | }; |
nothing calls this directly
no test coverage detected