| //===- WithColor.cpp ------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Support/WithColor.h" | |
| #include "DebugOptions.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #include "llvm/Support/Error.h" | |
| #include "llvm/Support/ManagedStatic.h" | |
| using namespace llvm; | |
| cl::OptionCategory &llvm::getColorCategory() { | |
| static cl::OptionCategory ColorCategory("Color Options"); | |
| return ColorCategory; | |
| } | |
| namespace { | |
| struct CreateUseColor { | |
| static void *call() { | |
| return new cl::opt<cl::boolOrDefault>( | |
| "color", cl::cat(getColorCategory()), | |
| cl::desc("Use colors in output (default=autodetect)"), | |
| cl::init(cl::boolOrDefault::BOU_UNSET)); | |
| } | |
| }; | |
| } // namespace | |
| static ManagedStatic<cl::opt<cl::boolOrDefault>, CreateUseColor> UseColor; | |
| void llvm::initWithColorOptions() { *UseColor; } | |
| static bool DefaultAutoDetectFunction(const raw_ostream &OS) { | |
| return *UseColor == cl::boolOrDefault::BOU_UNSET | |
| ? OS.has_colors() | |
| : *UseColor == cl::boolOrDefault::BOU_TRUE; | |
| } | |
| WithColor::AutoDetectFunctionType WithColor::AutoDetectFunction = | |
| DefaultAutoDetectFunction; | |
| WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode) | |
| : OS(OS), Mode(Mode) { | |
| // Detect color from terminal type unless the user passed the --color option. | |
| if (colorsEnabled()) { | |
| switch (Color) { | |
| case HighlightColor::Address: | |
| OS.changeColor(raw_ostream::YELLOW); | |
| break; | |
| case HighlightColor::String: | |
| OS.changeColor(raw_ostream::GREEN); | |
| break; | |
| case HighlightColor::Tag: | |
| OS.changeColor(raw_ostream::BLUE); | |
| break; | |
| case HighlightColor::Attribute: | |
| OS.changeColor(raw_ostream::CYAN); | |
| break; | |
| case HighlightColor::Enumerator: | |
| OS.changeColor(raw_ostream::MAGENTA); | |
| break; | |
| case HighlightColor::Macro: | |
| OS.changeColor(raw_ostream::RED); | |
| break; | |
| case HighlightColor::Error: | |
| OS.changeColor(raw_ostream::RED, true); | |
| break; | |
| case HighlightColor::Warning: | |
| OS.changeColor(raw_ostream::MAGENTA, true); | |
| break; | |
| case HighlightColor::Note: | |
| OS.changeColor(raw_ostream::BLACK, true); | |
| break; | |
| case HighlightColor::Remark: | |
| OS.changeColor(raw_ostream::BLUE, true); | |
| break; | |
| } | |
| } | |
| } | |
| raw_ostream &WithColor::error() { return error(errs()); } | |
| raw_ostream &WithColor::warning() { return warning(errs()); } | |
| raw_ostream &WithColor::note() { return note(errs()); } | |
| raw_ostream &WithColor::remark() { return remark(errs()); } | |
| raw_ostream &WithColor::error(raw_ostream &OS, StringRef Prefix, | |
| bool DisableColors) { | |
| if (!Prefix.empty()) | |
| OS << Prefix << ": "; | |
| return WithColor(OS, HighlightColor::Error, | |
| DisableColors ? ColorMode::Disable : ColorMode::Auto) | |
| .get() | |
| << "error: "; | |
| } | |
| raw_ostream &WithColor::warning(raw_ostream &OS, StringRef Prefix, | |
| bool DisableColors) { | |
| if (!Prefix.empty()) | |
| OS << Prefix << ": "; | |
| return WithColor(OS, HighlightColor::Warning, | |
| DisableColors ? ColorMode::Disable : ColorMode::Auto) | |
| .get() | |
| << "warning: "; | |
| } | |
| raw_ostream &WithColor::note(raw_ostream &OS, StringRef Prefix, | |
| bool DisableColors) { | |
| if (!Prefix.empty()) | |
| OS << Prefix << ": "; | |
| return WithColor(OS, HighlightColor::Note, | |
| DisableColors ? ColorMode::Disable : ColorMode::Auto) | |
| .get() | |
| << "note: "; | |
| } | |
| raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix, | |
| bool DisableColors) { | |
| if (!Prefix.empty()) | |
| OS << Prefix << ": "; | |
| return WithColor(OS, HighlightColor::Remark, | |
| DisableColors ? ColorMode::Disable : ColorMode::Auto) | |
| .get() | |
| << "remark: "; | |
| } | |
| bool WithColor::colorsEnabled() { | |
| switch (Mode) { | |
| case ColorMode::Enable: | |
| return true; | |
| case ColorMode::Disable: | |
| return false; | |
| case ColorMode::Auto: | |
| return AutoDetectFunction(OS); | |
| } | |
| llvm_unreachable("All cases handled above."); | |
| } | |
| WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold, | |
| bool BG) { | |
| if (colorsEnabled()) | |
| OS.changeColor(Color, Bold, BG); | |
| return *this; | |
| } | |
| WithColor &WithColor::resetColor() { | |
| if (colorsEnabled()) | |
| OS.resetColor(); | |
| return *this; | |
| } | |
| WithColor::~WithColor() { resetColor(); } | |
| void WithColor::defaultErrorHandler(Error Err) { | |
| handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) { | |
| WithColor::error() << Info.message() << '\n'; | |
| }); | |
| } | |
| void WithColor::defaultWarningHandler(Error Warning) { | |
| handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) { | |
| WithColor::warning() << Info.message() << '\n'; | |
| }); | |
| } | |
| WithColor::AutoDetectFunctionType WithColor::defaultAutoDetectFunction() { | |
| return DefaultAutoDetectFunction; | |
| } | |
| void WithColor::setAutoDetectFunction( | |
| AutoDetectFunctionType NewAutoDetectFunction) { | |
| AutoDetectFunction = NewAutoDetectFunction; | |
| } |