19b851527SJacques Pienaar //===- IndentedOstream.cpp - raw ostream wrapper to indent ----------------===// 29b851527SJacques Pienaar // 39b851527SJacques Pienaar // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 49b851527SJacques Pienaar // See https://llvm.org/LICENSE.txt for license information. 59b851527SJacques Pienaar // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 69b851527SJacques Pienaar // 79b851527SJacques Pienaar //===----------------------------------------------------------------------===// 89b851527SJacques Pienaar // 99b851527SJacques Pienaar // raw_ostream subclass that keeps track of indentation for textual output 109b851527SJacques Pienaar // where indentation helps readability. 119b851527SJacques Pienaar // 129b851527SJacques Pienaar //===----------------------------------------------------------------------===// 139b851527SJacques Pienaar 149b851527SJacques Pienaar #include "mlir/Support/IndentedOstream.h" 159b851527SJacques Pienaar 169b851527SJacques Pienaar using namespace mlir; 179b851527SJacques Pienaar 18*ca6bd9cdSMogball raw_indented_ostream & printReindented(StringRef str)19*ca6bd9cdSMogballmlir::raw_indented_ostream::printReindented(StringRef str) { 20*ca6bd9cdSMogball StringRef output = str; 21*ca6bd9cdSMogball // Skip empty lines. 22*ca6bd9cdSMogball while (!output.empty()) { 23*ca6bd9cdSMogball auto split = output.split('\n'); 249b851527SJacques Pienaar size_t indent = split.first.find_first_not_of(" \t"); 259b851527SJacques Pienaar if (indent != StringRef::npos) { 26*ca6bd9cdSMogball // Set an initial value. 279b851527SJacques Pienaar leadingWs = indent; 289b851527SJacques Pienaar break; 299b851527SJacques Pienaar } 30*ca6bd9cdSMogball output = split.second; 31*ca6bd9cdSMogball } 32*ca6bd9cdSMogball // Determine the maximum indent. 33*ca6bd9cdSMogball StringRef remaining = output; 34*ca6bd9cdSMogball while (!remaining.empty()) { 35*ca6bd9cdSMogball auto split = remaining.split('\n'); 36*ca6bd9cdSMogball size_t indent = split.first.find_first_not_of(" \t"); 37*ca6bd9cdSMogball if (indent != StringRef::npos) 38*ca6bd9cdSMogball leadingWs = std::min(leadingWs, static_cast<int>(indent)); 399b851527SJacques Pienaar remaining = split.second; 409b851527SJacques Pienaar } 419b851527SJacques Pienaar // Print, skipping the empty lines. 42*ca6bd9cdSMogball *this << output; 439b851527SJacques Pienaar leadingWs = 0; 449b851527SJacques Pienaar return *this; 459b851527SJacques Pienaar } 469b851527SJacques Pienaar write_impl(const char * ptr,size_t size)479b851527SJacques Pienaarvoid mlir::raw_indented_ostream::write_impl(const char *ptr, size_t size) { 489b851527SJacques Pienaar StringRef str(ptr, size); 499b851527SJacques Pienaar // Print out indented. 509b851527SJacques Pienaar auto print = [this](StringRef str) { 519b851527SJacques Pienaar if (atStartOfLine) 529b851527SJacques Pienaar os.indent(currentIndent) << str.substr(leadingWs); 539b851527SJacques Pienaar else 549b851527SJacques Pienaar os << str.substr(leadingWs); 559b851527SJacques Pienaar }; 569b851527SJacques Pienaar 579b851527SJacques Pienaar while (!str.empty()) { 589b851527SJacques Pienaar size_t idx = str.find('\n'); 599b851527SJacques Pienaar if (idx == StringRef::npos) { 609b851527SJacques Pienaar if (!str.substr(leadingWs).empty()) { 619b851527SJacques Pienaar print(str); 629b851527SJacques Pienaar atStartOfLine = false; 639b851527SJacques Pienaar } 649b851527SJacques Pienaar break; 659b851527SJacques Pienaar } 669b851527SJacques Pienaar 679b851527SJacques Pienaar auto split = 689b851527SJacques Pienaar std::make_pair(str.slice(0, idx), str.slice(idx + 1, StringRef::npos)); 699b851527SJacques Pienaar // Print empty new line without spaces if line only has spaces. 709b851527SJacques Pienaar if (!split.first.ltrim().empty()) 719b851527SJacques Pienaar print(split.first); 729b851527SJacques Pienaar os << '\n'; 739b851527SJacques Pienaar atStartOfLine = true; 749b851527SJacques Pienaar str = split.second; 759b851527SJacques Pienaar } 769b851527SJacques Pienaar } 77