1 //===- WithColor.cpp ------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Support/WithColor.h"
11 #include "DebugOptions.h"
13 #include "llvm/Support/CommandLine.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/Support/ManagedStatic.h"
19 cl::OptionCategory
&llvm::getColorCategory() {
20 static cl::OptionCategory
ColorCategory("Color Options");
24 struct CreateUseColor
{
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
));
33 static ManagedStatic
<cl::opt
<cl::boolOrDefault
>, CreateUseColor
> UseColor
;
34 void llvm::initWithColorOptions() { *UseColor
; }
36 static bool DefaultAutoDetectFunction(const raw_ostream
&OS
) {
37 return *UseColor
== cl::BOU_UNSET
? OS
.has_colors()
38 : *UseColor
== cl::BOU_TRUE
;
41 WithColor::AutoDetectFunctionType
WithColor::AutoDetectFunction
=
42 DefaultAutoDetectFunction
;
44 WithColor::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()) {
49 case HighlightColor::Address
:
50 OS
.changeColor(raw_ostream::YELLOW
);
52 case HighlightColor::String
:
53 OS
.changeColor(raw_ostream::GREEN
);
55 case HighlightColor::Tag
:
56 OS
.changeColor(raw_ostream::BLUE
);
58 case HighlightColor::Attribute
:
59 OS
.changeColor(raw_ostream::CYAN
);
61 case HighlightColor::Enumerator
:
62 OS
.changeColor(raw_ostream::MAGENTA
);
64 case HighlightColor::Macro
:
65 OS
.changeColor(raw_ostream::RED
);
67 case HighlightColor::Error
:
68 OS
.changeColor(raw_ostream::RED
, true);
70 case HighlightColor::Warning
:
71 OS
.changeColor(raw_ostream::MAGENTA
, true);
73 case HighlightColor::Note
:
74 OS
.changeColor(raw_ostream::BLACK
, true);
76 case HighlightColor::Remark
:
77 OS
.changeColor(raw_ostream::BLUE
, true);
83 raw_ostream
&WithColor::error() { return error(errs()); }
85 raw_ostream
&WithColor::warning() { return warning(errs()); }
87 raw_ostream
&WithColor::note() { return note(errs()); }
89 raw_ostream
&WithColor::remark() { return remark(errs()); }
91 raw_ostream
&WithColor::error(raw_ostream
&OS
, StringRef Prefix
,
95 return WithColor(OS
, HighlightColor::Error
,
96 DisableColors
? ColorMode::Disable
: ColorMode::Auto
)
101 raw_ostream
&WithColor::warning(raw_ostream
&OS
, StringRef Prefix
,
102 bool DisableColors
) {
104 OS
<< Prefix
<< ": ";
105 return WithColor(OS
, HighlightColor::Warning
,
106 DisableColors
? ColorMode::Disable
: ColorMode::Auto
)
111 raw_ostream
&WithColor::note(raw_ostream
&OS
, StringRef Prefix
,
112 bool DisableColors
) {
114 OS
<< Prefix
<< ": ";
115 return WithColor(OS
, HighlightColor::Note
,
116 DisableColors
? ColorMode::Disable
: ColorMode::Auto
)
121 raw_ostream
&WithColor::remark(raw_ostream
&OS
, StringRef Prefix
,
122 bool DisableColors
) {
124 OS
<< Prefix
<< ": ";
125 return WithColor(OS
, HighlightColor::Remark
,
126 DisableColors
? ColorMode::Disable
: ColorMode::Auto
)
131 bool WithColor::colorsEnabled() {
133 case ColorMode::Enable
:
135 case ColorMode::Disable
:
137 case ColorMode::Auto
:
138 return AutoDetectFunction(OS
);
140 llvm_unreachable("All cases handled above.");
143 WithColor
&WithColor::changeColor(raw_ostream::Colors Color
, bool Bold
,
146 OS
.changeColor(Color
, Bold
, BG
);
150 WithColor
&WithColor::resetColor() {
156 WithColor::~WithColor() { resetColor(); }
158 void WithColor::defaultErrorHandler(Error Err
) {
159 handleAllErrors(std::move(Err
), [](ErrorInfoBase
&Info
) {
160 WithColor::error() << Info
.message() << '\n';
164 void WithColor::defaultWarningHandler(Error Warning
) {
165 handleAllErrors(std::move(Warning
), [](ErrorInfoBase
&Info
) {
166 WithColor::warning() << Info
.message() << '\n';
170 WithColor::AutoDetectFunctionType
WithColor::defaultAutoDetectFunction() {
171 return DefaultAutoDetectFunction
;
174 void WithColor::setAutoDetectFunction(
175 AutoDetectFunctionType NewAutoDetectFunction
) {
176 AutoDetectFunction
= NewAutoDetectFunction
;