169217539SJonas Devlieghere //===- WithColor.cpp ------------------------------------------------------===//
269217539SJonas Devlieghere //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
669217539SJonas Devlieghere //
769217539SJonas Devlieghere //===----------------------------------------------------------------------===//
869217539SJonas Devlieghere
969217539SJonas Devlieghere #include "llvm/Support/WithColor.h"
1076374573SMehdi Amini
1176374573SMehdi Amini #include "DebugOptions.h"
1276374573SMehdi Amini
13ddc6ec94SSimon Pilgrim #include "llvm/Support/CommandLine.h"
14ba7a92c0SNico Weber #include "llvm/Support/Error.h"
1576374573SMehdi Amini #include "llvm/Support/ManagedStatic.h"
1669217539SJonas Devlieghere
1769217539SJonas Devlieghere using namespace llvm;
1869217539SJonas Devlieghere
getColorCategory()1976374573SMehdi Amini cl::OptionCategory &llvm::getColorCategory() {
2076374573SMehdi Amini static cl::OptionCategory ColorCategory("Color Options");
2176374573SMehdi Amini return ColorCategory;
2276374573SMehdi Amini }
2376374573SMehdi Amini namespace {
2476374573SMehdi Amini struct CreateUseColor {
call__anonefd7f0a70111::CreateUseColor2576374573SMehdi Amini static void *call() {
2676374573SMehdi Amini return new cl::opt<cl::boolOrDefault>(
2776374573SMehdi Amini "color", cl::cat(getColorCategory()),
2827126f52SJonas Devlieghere cl::desc("Use colors in output (default=autodetect)"),
2969217539SJonas Devlieghere cl::init(cl::BOU_UNSET));
3076374573SMehdi Amini }
3176374573SMehdi Amini };
3276374573SMehdi Amini } // namespace
3376374573SMehdi Amini static ManagedStatic<cl::opt<cl::boolOrDefault>, CreateUseColor> UseColor;
initWithColorOptions()3476374573SMehdi Amini void llvm::initWithColorOptions() { *UseColor; }
3569217539SJonas Devlieghere
DefaultAutoDetectFunction(const raw_ostream & OS)36*4429cf14SJonas Devlieghere static bool DefaultAutoDetectFunction(const raw_ostream &OS) {
37*4429cf14SJonas Devlieghere return *UseColor == cl::BOU_UNSET ? OS.has_colors()
38*4429cf14SJonas Devlieghere : *UseColor == cl::BOU_TRUE;
39*4429cf14SJonas Devlieghere }
40*4429cf14SJonas Devlieghere
41*4429cf14SJonas Devlieghere WithColor::AutoDetectFunctionType WithColor::AutoDetectFunction =
42*4429cf14SJonas Devlieghere DefaultAutoDetectFunction;
43*4429cf14SJonas Devlieghere
WithColor(raw_ostream & OS,HighlightColor Color,ColorMode Mode)44550b5995SJonas Devlieghere WithColor::WithColor(raw_ostream &OS, HighlightColor Color, ColorMode Mode)
45550b5995SJonas Devlieghere : OS(OS), Mode(Mode) {
4669217539SJonas Devlieghere // Detect color from terminal type unless the user passed the --color option.
473e66509fSJoel E. Denny if (colorsEnabled()) {
4869217539SJonas Devlieghere switch (Color) {
4969217539SJonas Devlieghere case HighlightColor::Address:
5069217539SJonas Devlieghere OS.changeColor(raw_ostream::YELLOW);
5169217539SJonas Devlieghere break;
5269217539SJonas Devlieghere case HighlightColor::String:
5369217539SJonas Devlieghere OS.changeColor(raw_ostream::GREEN);
5469217539SJonas Devlieghere break;
5569217539SJonas Devlieghere case HighlightColor::Tag:
5669217539SJonas Devlieghere OS.changeColor(raw_ostream::BLUE);
5769217539SJonas Devlieghere break;
5869217539SJonas Devlieghere case HighlightColor::Attribute:
5969217539SJonas Devlieghere OS.changeColor(raw_ostream::CYAN);
6069217539SJonas Devlieghere break;
6169217539SJonas Devlieghere case HighlightColor::Enumerator:
6269217539SJonas Devlieghere OS.changeColor(raw_ostream::MAGENTA);
6369217539SJonas Devlieghere break;
6469217539SJonas Devlieghere case HighlightColor::Macro:
6569217539SJonas Devlieghere OS.changeColor(raw_ostream::RED);
6669217539SJonas Devlieghere break;
6769217539SJonas Devlieghere case HighlightColor::Error:
6869217539SJonas Devlieghere OS.changeColor(raw_ostream::RED, true);
6969217539SJonas Devlieghere break;
7069217539SJonas Devlieghere case HighlightColor::Warning:
7169217539SJonas Devlieghere OS.changeColor(raw_ostream::MAGENTA, true);
7269217539SJonas Devlieghere break;
7369217539SJonas Devlieghere case HighlightColor::Note:
7469217539SJonas Devlieghere OS.changeColor(raw_ostream::BLACK, true);
7569217539SJonas Devlieghere break;
763e66509fSJoel E. Denny case HighlightColor::Remark:
773e66509fSJoel E. Denny OS.changeColor(raw_ostream::BLUE, true);
783e66509fSJoel E. Denny break;
7969217539SJonas Devlieghere }
8069217539SJonas Devlieghere }
8169217539SJonas Devlieghere }
8269217539SJonas Devlieghere
error()836be1f019SJonas Devlieghere raw_ostream &WithColor::error() { return error(errs()); }
846be1f019SJonas Devlieghere
warning()856be1f019SJonas Devlieghere raw_ostream &WithColor::warning() { return warning(errs()); }
866be1f019SJonas Devlieghere
note()876be1f019SJonas Devlieghere raw_ostream &WithColor::note() { return note(errs()); }
886be1f019SJonas Devlieghere
remark()893e66509fSJoel E. Denny raw_ostream &WithColor::remark() { return remark(errs()); }
903e66509fSJoel E. Denny
error(raw_ostream & OS,StringRef Prefix,bool DisableColors)913e66509fSJoel E. Denny raw_ostream &WithColor::error(raw_ostream &OS, StringRef Prefix,
923e66509fSJoel E. Denny bool DisableColors) {
93578c0494SJonas Devlieghere if (!Prefix.empty())
94578c0494SJonas Devlieghere OS << Prefix << ": ";
95550b5995SJonas Devlieghere return WithColor(OS, HighlightColor::Error,
96550b5995SJonas Devlieghere DisableColors ? ColorMode::Disable : ColorMode::Auto)
97550b5995SJonas Devlieghere .get()
983e66509fSJoel E. Denny << "error: ";
993072b130SJonas Devlieghere }
1003072b130SJonas Devlieghere
warning(raw_ostream & OS,StringRef Prefix,bool DisableColors)1013e66509fSJoel E. Denny raw_ostream &WithColor::warning(raw_ostream &OS, StringRef Prefix,
1023e66509fSJoel E. Denny bool DisableColors) {
103578c0494SJonas Devlieghere if (!Prefix.empty())
104578c0494SJonas Devlieghere OS << Prefix << ": ";
105550b5995SJonas Devlieghere return WithColor(OS, HighlightColor::Warning,
106550b5995SJonas Devlieghere DisableColors ? ColorMode::Disable : ColorMode::Auto)
107550b5995SJonas Devlieghere .get()
1083e66509fSJoel E. Denny << "warning: ";
1093072b130SJonas Devlieghere }
1103072b130SJonas Devlieghere
note(raw_ostream & OS,StringRef Prefix,bool DisableColors)1113e66509fSJoel E. Denny raw_ostream &WithColor::note(raw_ostream &OS, StringRef Prefix,
1123e66509fSJoel E. Denny bool DisableColors) {
113578c0494SJonas Devlieghere if (!Prefix.empty())
114578c0494SJonas Devlieghere OS << Prefix << ": ";
115550b5995SJonas Devlieghere return WithColor(OS, HighlightColor::Note,
116550b5995SJonas Devlieghere DisableColors ? ColorMode::Disable : ColorMode::Auto)
117550b5995SJonas Devlieghere .get()
118550b5995SJonas Devlieghere << "note: ";
1193072b130SJonas Devlieghere }
1203072b130SJonas Devlieghere
remark(raw_ostream & OS,StringRef Prefix,bool DisableColors)1213e66509fSJoel E. Denny raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix,
1223e66509fSJoel E. Denny bool DisableColors) {
1233e66509fSJoel E. Denny if (!Prefix.empty())
1243e66509fSJoel E. Denny OS << Prefix << ": ";
125550b5995SJonas Devlieghere return WithColor(OS, HighlightColor::Remark,
126550b5995SJonas Devlieghere DisableColors ? ColorMode::Disable : ColorMode::Auto)
127550b5995SJonas Devlieghere .get()
1283e66509fSJoel E. Denny << "remark: ";
1293e66509fSJoel E. Denny }
1303e66509fSJoel E. Denny
colorsEnabled()1313e66509fSJoel E. Denny bool WithColor::colorsEnabled() {
132550b5995SJonas Devlieghere switch (Mode) {
133550b5995SJonas Devlieghere case ColorMode::Enable:
134550b5995SJonas Devlieghere return true;
135550b5995SJonas Devlieghere case ColorMode::Disable:
1363e66509fSJoel E. Denny return false;
137550b5995SJonas Devlieghere case ColorMode::Auto:
138*4429cf14SJonas Devlieghere return AutoDetectFunction(OS);
139550b5995SJonas Devlieghere }
140550b5995SJonas Devlieghere llvm_unreachable("All cases handled above.");
1413e66509fSJoel E. Denny }
1423e66509fSJoel E. Denny
changeColor(raw_ostream::Colors Color,bool Bold,bool BG)1434d41c332SRui Ueyama WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold,
1444d41c332SRui Ueyama bool BG) {
1453e66509fSJoel E. Denny if (colorsEnabled())
1464d41c332SRui Ueyama OS.changeColor(Color, Bold, BG);
1473e66509fSJoel E. Denny return *this;
1483e66509fSJoel E. Denny }
1493e66509fSJoel E. Denny
resetColor()1503e66509fSJoel E. Denny WithColor &WithColor::resetColor() {
1513e66509fSJoel E. Denny if (colorsEnabled())
15269217539SJonas Devlieghere OS.resetColor();
1533e66509fSJoel E. Denny return *this;
15469217539SJonas Devlieghere }
1553e66509fSJoel E. Denny
~WithColor()1563e66509fSJoel E. Denny WithColor::~WithColor() { resetColor(); }
157c187364dSAlexey Lapshin
defaultErrorHandler(Error Err)158c187364dSAlexey Lapshin void WithColor::defaultErrorHandler(Error Err) {
159c187364dSAlexey Lapshin handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) {
160c187364dSAlexey Lapshin WithColor::error() << Info.message() << '\n';
161c187364dSAlexey Lapshin });
162c187364dSAlexey Lapshin }
163c187364dSAlexey Lapshin
defaultWarningHandler(Error Warning)164c187364dSAlexey Lapshin void WithColor::defaultWarningHandler(Error Warning) {
165c187364dSAlexey Lapshin handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
166c187364dSAlexey Lapshin WithColor::warning() << Info.message() << '\n';
167c187364dSAlexey Lapshin });
168c187364dSAlexey Lapshin }
169*4429cf14SJonas Devlieghere
defaultAutoDetectFunction()170*4429cf14SJonas Devlieghere WithColor::AutoDetectFunctionType WithColor::defaultAutoDetectFunction() {
171*4429cf14SJonas Devlieghere return DefaultAutoDetectFunction;
172*4429cf14SJonas Devlieghere }
173*4429cf14SJonas Devlieghere
setAutoDetectFunction(AutoDetectFunctionType NewAutoDetectFunction)174*4429cf14SJonas Devlieghere void WithColor::setAutoDetectFunction(
175*4429cf14SJonas Devlieghere AutoDetectFunctionType NewAutoDetectFunction) {
176*4429cf14SJonas Devlieghere AutoDetectFunction = NewAutoDetectFunction;
177*4429cf14SJonas Devlieghere }
178