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