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