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*ca6bd9cdSMogball mlir::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 Pienaar void 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