#include "DiffPrinter.h" #include "llvm/Support/FormatAdapters.h" using namespace llvm; using namespace llvm::pdb; namespace { struct Colorize { Colorize(raw_ostream &OS, DiffResult Result) : OS(OS) { if (!OS.has_colors()) return; switch (Result) { case DiffResult::IDENTICAL: OS.changeColor(raw_ostream::Colors::GREEN, false); break; case DiffResult::EQUIVALENT: OS.changeColor(raw_ostream::Colors::YELLOW, true); break; default: OS.changeColor(raw_ostream::Colors::RED, false); break; } } ~Colorize() { if (OS.has_colors()) OS.resetColor(); } raw_ostream &OS; }; } DiffPrinter::DiffPrinter(uint32_t Indent, StringRef Header, uint32_t PropertyWidth, uint32_t FieldWidth, bool Result, bool Fields, raw_ostream &Stream) : PrintResult(Result), PrintValues(Fields), Indent(Indent), PropertyWidth(PropertyWidth), FieldWidth(FieldWidth), OS(Stream) { printHeaderRow(); printFullRow(Header); } DiffPrinter::~DiffPrinter() {} uint32_t DiffPrinter::tableWidth() const { // `|` uint32_t W = 1; // `|` W += PropertyWidth + 1; if (PrintResult) { // ` I |` W += 4; } if (PrintValues) { // `||` W += 2 * (FieldWidth + 1); } return W; } void DiffPrinter::printFullRow(StringRef Text) { newLine(); printValue(Text, DiffResult::UNSPECIFIED, AlignStyle::Center, tableWidth() - 2, true); printSeparatorRow(); } void DiffPrinter::printSeparatorRow() { newLine(); OS << formatv("{0}", fmt_repeat('-', PropertyWidth)); if (PrintResult) { OS << '+'; OS << formatv("{0}", fmt_repeat('-', 3)); } if (PrintValues) { OS << '+'; OS << formatv("{0}", fmt_repeat('-', FieldWidth)); OS << '+'; OS << formatv("{0}", fmt_repeat('-', FieldWidth)); } OS << '|'; } void DiffPrinter::printHeaderRow() { newLine('-'); OS << formatv("{0}", fmt_repeat('-', tableWidth() - 1)); } void DiffPrinter::newLine(char InitialChar) { OS << "\n"; OS.indent(Indent) << InitialChar; } void DiffPrinter::printExplicit(StringRef Property, DiffResult C, StringRef Left, StringRef Right) { newLine(); printValue(Property, DiffResult::UNSPECIFIED, AlignStyle::Right, PropertyWidth, true); printResult(C); printValue(Left, C, AlignStyle::Center, FieldWidth, false); printValue(Right, C, AlignStyle::Center, FieldWidth, false); printSeparatorRow(); } void DiffPrinter::printResult(DiffResult Result) { if (!PrintResult) return; switch (Result) { case DiffResult::DIFFERENT: printValue("D", Result, AlignStyle::Center, 3, true); break; case DiffResult::EQUIVALENT: printValue("E", Result, AlignStyle::Center, 3, true); break; case DiffResult::IDENTICAL: printValue("I", Result, AlignStyle::Center, 3, true); break; case DiffResult::UNSPECIFIED: printValue(" ", Result, AlignStyle::Center, 3, true); break; } } void DiffPrinter::printValue(StringRef Value, DiffResult C, AlignStyle Style, uint32_t Width, bool Force) { if (!Force && !PrintValues) return; if (Style == AlignStyle::Right) --Width; std::string FormattedItem = formatv("{0}", fmt_align(Value, Style, Width)).str(); if (C != DiffResult::UNSPECIFIED) { Colorize Color(OS, C); OS << FormattedItem; } else OS << FormattedItem; if (Style == AlignStyle::Right) OS << ' '; OS << '|'; }