1 //===- WithColor.cpp ------------------------------------------------------===// 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 #include "llvm/Support/WithColor.h" 10 #include "llvm/Support/raw_ostream.h" 11 12 using namespace llvm; 13 14 cl::OptionCategory llvm::ColorCategory("Color Options"); 15 16 static cl::opt<cl::boolOrDefault> 17 UseColor("color", cl::cat(ColorCategory), 18 cl::desc("Use colors in output (default=autodetect)"), 19 cl::init(cl::BOU_UNSET)); 20 21 WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode) 22 : OS(OS), Mode(Mode) { 23 // Detect color from terminal type unless the user passed the --color option. 24 if (colorsEnabled()) { 25 switch (Color) { 26 case HighlightColor::Address: 27 OS.changeColor(raw_ostream::YELLOW); 28 break; 29 case HighlightColor::String: 30 OS.changeColor(raw_ostream::GREEN); 31 break; 32 case HighlightColor::Tag: 33 OS.changeColor(raw_ostream::BLUE); 34 break; 35 case HighlightColor::Attribute: 36 OS.changeColor(raw_ostream::CYAN); 37 break; 38 case HighlightColor::Enumerator: 39 OS.changeColor(raw_ostream::MAGENTA); 40 break; 41 case HighlightColor::Macro: 42 OS.changeColor(raw_ostream::RED); 43 break; 44 case HighlightColor::Error: 45 OS.changeColor(raw_ostream::RED, true); 46 break; 47 case HighlightColor::Warning: 48 OS.changeColor(raw_ostream::MAGENTA, true); 49 break; 50 case HighlightColor::Note: 51 OS.changeColor(raw_ostream::BLACK, true); 52 break; 53 case HighlightColor::Remark: 54 OS.changeColor(raw_ostream::BLUE, true); 55 break; 56 } 57 } 58 } 59 60 raw_ostream &WithColor::error() { return error(errs()); } 61 62 raw_ostream &WithColor::warning() { return warning(errs()); } 63 64 raw_ostream &WithColor::note() { return note(errs()); } 65 66 raw_ostream &WithColor::remark() { return remark(errs()); } 67 68 raw_ostream &WithColor::error(raw_ostream &OS, StringRef Prefix, 69 bool DisableColors) { 70 if (!Prefix.empty()) 71 OS << Prefix << ": "; 72 return WithColor(OS, HighlightColor::Error, 73 DisableColors ? ColorMode::Disable : ColorMode::Auto) 74 .get() 75 << "error: "; 76 } 77 78 raw_ostream &WithColor::warning(raw_ostream &OS, StringRef Prefix, 79 bool DisableColors) { 80 if (!Prefix.empty()) 81 OS << Prefix << ": "; 82 return WithColor(OS, HighlightColor::Warning, 83 DisableColors ? ColorMode::Disable : ColorMode::Auto) 84 .get() 85 << "warning: "; 86 } 87 88 raw_ostream &WithColor::note(raw_ostream &OS, StringRef Prefix, 89 bool DisableColors) { 90 if (!Prefix.empty()) 91 OS << Prefix << ": "; 92 return WithColor(OS, HighlightColor::Note, 93 DisableColors ? ColorMode::Disable : ColorMode::Auto) 94 .get() 95 << "note: "; 96 } 97 98 raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix, 99 bool DisableColors) { 100 if (!Prefix.empty()) 101 OS << Prefix << ": "; 102 return WithColor(OS, HighlightColor::Remark, 103 DisableColors ? ColorMode::Disable : ColorMode::Auto) 104 .get() 105 << "remark: "; 106 } 107 108 bool WithColor::colorsEnabled() { 109 switch (Mode) { 110 case ColorMode::Enable: 111 return true; 112 case ColorMode::Disable: 113 return false; 114 case ColorMode::Auto: 115 return UseColor == cl::BOU_UNSET ? OS.has_colors() 116 : UseColor == cl::BOU_TRUE; 117 } 118 llvm_unreachable("All cases handled above."); 119 } 120 121 WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold, 122 bool BG) { 123 if (colorsEnabled()) 124 OS.changeColor(Color, Bold, BG); 125 return *this; 126 } 127 128 WithColor &WithColor::resetColor() { 129 if (colorsEnabled()) 130 OS.resetColor(); 131 return *this; 132 } 133 134 WithColor::~WithColor() { resetColor(); } 135 136 void WithColor::defaultErrorHandler(Error Err) { 137 handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) { 138 WithColor::error() << Info.message() << '\n'; 139 }); 140 } 141 142 void WithColor::defaultWarningHandler(Error Warning) { 143 handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) { 144 WithColor::warning() << Info.message() << '\n'; 145 }); 146 } 147