| 512 | } |
| 513 | |
| 514 | std::string Source::DisplayErrorLocation(SourceLocation location) const { |
| 515 | constexpr char32_t kDot = '.'; |
| 516 | constexpr char32_t kHat = '^'; |
| 517 | |
| 518 | constexpr char32_t kWideDot = 0xff0e; |
| 519 | constexpr char32_t kWideHat = 0xff3e; |
| 520 | absl::optional<std::string> snippet = Snippet(location.line); |
| 521 | if (!snippet || snippet->empty()) { |
| 522 | return ""; |
| 523 | } |
| 524 | |
| 525 | *snippet = absl::StrReplaceAll(*snippet, {{"\t", " "}}); |
| 526 | absl::string_view snippet_view(*snippet); |
| 527 | std::string result; |
| 528 | absl::StrAppend(&result, "\n | ", *snippet); |
| 529 | absl::StrAppend(&result, "\n | "); |
| 530 | |
| 531 | std::string index_line; |
| 532 | for (int32_t i = 0; i < location.column && !snippet_view.empty(); ++i) { |
| 533 | size_t count; |
| 534 | std::tie(std::ignore, count) = internal::Utf8Decode(snippet_view); |
| 535 | snippet_view.remove_prefix(count); |
| 536 | if (count > 1) { |
| 537 | internal::Utf8Encode(index_line, kWideDot); |
| 538 | } else { |
| 539 | internal::Utf8Encode(index_line, kDot); |
| 540 | } |
| 541 | } |
| 542 | size_t count = 0; |
| 543 | if (!snippet_view.empty()) { |
| 544 | std::tie(std::ignore, count) = internal::Utf8Decode(snippet_view); |
| 545 | } |
| 546 | if (count > 1) { |
| 547 | internal::Utf8Encode(index_line, kWideHat); |
| 548 | } else { |
| 549 | internal::Utf8Encode(index_line, kHat); |
| 550 | } |
| 551 | absl::StrAppend(&result, index_line); |
| 552 | return result; |
| 553 | } |
| 554 | |
| 555 | absl::optional<SourcePosition> Source::FindLinePosition(int32_t line) const { |
| 556 | if (ABSL_PREDICT_FALSE(line < 1)) { |
no test coverage detected