| 2113 | } |
| 2114 | |
| 2115 | void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length, |
| 2116 | cmCTestTypes::TruncationMode truncate) |
| 2117 | { |
| 2118 | if (!length || length >= output.size() || |
| 2119 | output.find("CTEST_FULL_OUTPUT") != std::string::npos) { |
| 2120 | return; |
| 2121 | } |
| 2122 | |
| 2123 | // Advance n bytes in string delimited by begin/end but do not break in the |
| 2124 | // middle of a multi-byte UTF-8 encoding. |
| 2125 | auto utf8_advance = [](char const* const begin, char const* const end, |
| 2126 | size_t n) -> char const* { |
| 2127 | char const* const stop = begin + n; |
| 2128 | char const* current = begin; |
| 2129 | while (current < stop) { |
| 2130 | unsigned int ch; |
| 2131 | if (char const* next = cm_utf8_decode_character(current, end, &ch)) { |
| 2132 | if (next > stop) { |
| 2133 | break; |
| 2134 | } |
| 2135 | current = next; |
| 2136 | } else // Bad byte will be handled by cmXMLWriter. |
| 2137 | { |
| 2138 | ++current; |
| 2139 | } |
| 2140 | } |
| 2141 | return current; |
| 2142 | }; |
| 2143 | |
| 2144 | // Truncation message. |
| 2145 | std::string const msg = |
| 2146 | cmStrCat("\n[This part of the test output was removed since it exceeds " |
| 2147 | "the threshold of ", |
| 2148 | length, " bytes.]\n"); |
| 2149 | |
| 2150 | char const* const begin = output.c_str(); |
| 2151 | char const* const end = begin + output.size(); |
| 2152 | |
| 2153 | // Erase head, middle or tail of output. |
| 2154 | if (truncate == cmCTestTypes::TruncationMode::Head) { |
| 2155 | char const* current = utf8_advance(begin, end, output.size() - length); |
| 2156 | output.erase(0, current - begin); |
| 2157 | output.insert(0, msg + "..."); |
| 2158 | } else if (truncate == cmCTestTypes::TruncationMode::Middle) { |
| 2159 | char const* current = utf8_advance(begin, end, length / 2); |
| 2160 | output.erase(current - begin, output.size() - length); |
| 2161 | output.insert(current - begin, "..." + msg + "..."); |
| 2162 | } else { // default or "tail" |
| 2163 | char const* current = utf8_advance(begin, end, length); |
| 2164 | output.erase(current - begin); |
| 2165 | output += ("..." + msg); |
| 2166 | } |
| 2167 | } |
| 2168 | |
| 2169 | void cmCTestTestHandler::cmCTestTestProperties::AppendError( |
| 2170 | cm::string_view err) |