diff --git a/mlir/include/mlir/Support/IndentedOstream.h b/mlir/include/mlir/Support/IndentedOstream.h --- a/mlir/include/mlir/Support/IndentedOstream.h +++ b/mlir/include/mlir/Support/IndentedOstream.h @@ -117,7 +117,9 @@ // Skip empty lines. while (!output.empty()) { auto split = output.split('\n'); - size_t indent = split.first.find_first_not_of(" \t"); + // Trim Windows \r characters from \r\n line endings. + auto firstTrimmed = split.first.rtrim('\r'); + size_t indent = firstTrimmed.find_first_not_of(" \t"); if (indent != StringRef::npos) { // Set an initial value. leadingWs = indent; @@ -129,7 +131,8 @@ StringRef remaining = output; while (!remaining.empty()) { auto split = remaining.split('\n'); - size_t indent = split.first.find_first_not_of(" \t"); + auto firstTrimmed = split.first.rtrim('\r'); + size_t indent = firstTrimmed.find_first_not_of(" \t"); if (indent != StringRef::npos) leadingWs = std::min(leadingWs, static_cast(indent)); remaining = split.second; diff --git a/mlir/unittests/Support/IndentedOstreamTest.cpp b/mlir/unittests/Support/IndentedOstreamTest.cpp --- a/mlir/unittests/Support/IndentedOstreamTest.cpp +++ b/mlir/unittests/Support/IndentedOstreamTest.cpp @@ -108,3 +108,19 @@ )"; EXPECT_THAT(os.str(), StrEq(expected)); } + +TEST(FormatTest, ReindentLineEndings) { + std::string str; + llvm::raw_string_ostream os(str); + raw_indented_ostream ros(os); + + // Similar string as the previous test, but with \r\n (Windows style) line + // breaks. Note that C++'s internal string representation uses \n, so just + // running the previous test as-is on Windows is not sufficient. + const auto *desc = + "\r\n\r\n\r\n First line\r\n second line"; + ros.printReindented(desc); + ros.flush(); + const auto *expected = "First line\r\n second line"; + EXPECT_THAT(os.str(), StrEq(expected)); +}