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
13 using namespace llvm;
14
15 cl::OptionCategory llvm::ColorCategory("Color Options");
16
17 static 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
WithColor(raw_ostream & OS,HighlightColor Color,ColorMode Mode)22 WithColor::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
error()61 raw_ostream &WithColor::error() { return error(errs()); }
62
warning()63 raw_ostream &WithColor::warning() { return warning(errs()); }
64
note()65 raw_ostream &WithColor::note() { return note(errs()); }
66
remark()67 raw_ostream &WithColor::remark() { return remark(errs()); }
68
error(raw_ostream & OS,StringRef Prefix,bool DisableColors)69 raw_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
warning(raw_ostream & OS,StringRef Prefix,bool DisableColors)79 raw_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
note(raw_ostream & OS,StringRef Prefix,bool DisableColors)89 raw_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
remark(raw_ostream & OS,StringRef Prefix,bool DisableColors)99 raw_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
colorsEnabled()109 bool 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
changeColor(raw_ostream::Colors Color,bool Bold,bool BG)122 WithColor &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
resetColor()129 WithColor &WithColor::resetColor() {
130 if (colorsEnabled())
131 OS.resetColor();
132 return *this;
133 }
134
~WithColor()135 WithColor::~WithColor() { resetColor(); }
136
defaultErrorHandler(Error Err)137 void WithColor::defaultErrorHandler(Error Err) {
138 handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) {
139 WithColor::error() << Info.message() << '\n';
140 });
141 }
142
defaultWarningHandler(Error Warning)143 void WithColor::defaultWarningHandler(Error Warning) {
144 handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
145 WithColor::warning() << Info.message() << '\n';
146 });
147 }
148