1 //===- IndentedOstream.cpp - raw ostream wrapper to indent ----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // raw_ostream subclass that keeps track of indentation for textual output 10 // where indentation helps readability. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "mlir/Support/IndentedOstream.h" 15 16 using namespace mlir; 17 18 raw_indented_ostream & printReindented(StringRef str)19mlir::raw_indented_ostream::printReindented(StringRef str) { 20 StringRef output = str; 21 // Skip empty lines. 22 while (!output.empty()) { 23 auto split = output.split('\n'); 24 size_t indent = split.first.find_first_not_of(" \t"); 25 if (indent != StringRef::npos) { 26 // Set an initial value. 27 leadingWs = indent; 28 break; 29 } 30 output = split.second; 31 } 32 // Determine the maximum indent. 33 StringRef remaining = output; 34 while (!remaining.empty()) { 35 auto split = remaining.split('\n'); 36 size_t indent = split.first.find_first_not_of(" \t"); 37 if (indent != StringRef::npos) 38 leadingWs = std::min(leadingWs, static_cast<int>(indent)); 39 remaining = split.second; 40 } 41 // Print, skipping the empty lines. 42 *this << output; 43 leadingWs = 0; 44 return *this; 45 } 46 write_impl(const char * ptr,size_t size)47void mlir::raw_indented_ostream::write_impl(const char *ptr, size_t size) { 48 StringRef str(ptr, size); 49 // Print out indented. 50 auto print = [this](StringRef str) { 51 if (atStartOfLine) 52 os.indent(currentIndent) << str.substr(leadingWs); 53 else 54 os << str.substr(leadingWs); 55 }; 56 57 while (!str.empty()) { 58 size_t idx = str.find('\n'); 59 if (idx == StringRef::npos) { 60 if (!str.substr(leadingWs).empty()) { 61 print(str); 62 atStartOfLine = false; 63 } 64 break; 65 } 66 67 auto split = 68 std::make_pair(str.slice(0, idx), str.slice(idx + 1, StringRef::npos)); 69 // Print empty new line without spaces if line only has spaces. 70 if (!split.first.ltrim().empty()) 71 print(split.first); 72 os << '\n'; 73 atStartOfLine = true; 74 str = split.second; 75 } 76 } 77