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/raw_ostream.h"
11 
12 using namespace llvm;
13 
14 cl::OptionCategory llvm::ColorCategory("Color Options");
15 
16 static cl::opt<cl::boolOrDefault>
17     UseColor("color", cl::cat(ColorCategory),
18              cl::desc("Use colors in output (default=autodetect)"),
19              cl::init(cl::BOU_UNSET));
20 
21 WithColor::WithColor(raw_ostream &OS, HighlightColor Color, bool DisableColors)
22     : OS(OS), DisableColors(DisableColors) {
23   // Detect color from terminal type unless the user passed the --color option.
24   if (colorsEnabled()) {
25     switch (Color) {
26     case HighlightColor::Address:
27       OS.changeColor(raw_ostream::YELLOW);
28       break;
29     case HighlightColor::String:
30       OS.changeColor(raw_ostream::GREEN);
31       break;
32     case HighlightColor::Tag:
33       OS.changeColor(raw_ostream::BLUE);
34       break;
35     case HighlightColor::Attribute:
36       OS.changeColor(raw_ostream::CYAN);
37       break;
38     case HighlightColor::Enumerator:
39       OS.changeColor(raw_ostream::MAGENTA);
40       break;
41     case HighlightColor::Macro:
42       OS.changeColor(raw_ostream::RED);
43       break;
44     case HighlightColor::Error:
45       OS.changeColor(raw_ostream::RED, true);
46       break;
47     case HighlightColor::Warning:
48       OS.changeColor(raw_ostream::MAGENTA, true);
49       break;
50     case HighlightColor::Note:
51       OS.changeColor(raw_ostream::BLACK, true);
52       break;
53     case HighlightColor::Remark:
54       OS.changeColor(raw_ostream::BLUE, true);
55       break;
56     }
57   }
58 }
59 
60 raw_ostream &WithColor::error() { return error(errs()); }
61 
62 raw_ostream &WithColor::warning() { return warning(errs()); }
63 
64 raw_ostream &WithColor::note() { return note(errs()); }
65 
66 raw_ostream &WithColor::remark() { return remark(errs()); }
67 
68 raw_ostream &WithColor::error(raw_ostream &OS, StringRef Prefix,
69                               bool DisableColors) {
70   if (!Prefix.empty())
71     OS << Prefix << ": ";
72   return WithColor(OS, HighlightColor::Error, DisableColors).get()
73          << "error: ";
74 }
75 
76 raw_ostream &WithColor::warning(raw_ostream &OS, StringRef Prefix,
77                                 bool DisableColors) {
78   if (!Prefix.empty())
79     OS << Prefix << ": ";
80   return WithColor(OS, HighlightColor::Warning, DisableColors).get()
81          << "warning: ";
82 }
83 
84 raw_ostream &WithColor::note(raw_ostream &OS, StringRef Prefix,
85                              bool DisableColors) {
86   if (!Prefix.empty())
87     OS << Prefix << ": ";
88   return WithColor(OS, HighlightColor::Note, DisableColors).get() << "note: ";
89 }
90 
91 raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix,
92                                bool DisableColors) {
93   if (!Prefix.empty())
94     OS << Prefix << ": ";
95   return WithColor(OS, HighlightColor::Remark, DisableColors).get()
96          << "remark: ";
97 }
98 
99 bool WithColor::colorsEnabled() {
100   if (DisableColors)
101     return false;
102   if (UseColor == cl::BOU_UNSET)
103     return OS.has_colors();
104   return UseColor == cl::BOU_TRUE;
105 }
106 
107 WithColor &WithColor::changeColor(raw_ostream::Colors Color, bool Bold,
108                                   bool BG) {
109   if (colorsEnabled())
110     OS.changeColor(Color, Bold, BG);
111   return *this;
112 }
113 
114 WithColor &WithColor::resetColor() {
115   if (colorsEnabled())
116     OS.resetColor();
117   return *this;
118 }
119 
120 WithColor::~WithColor() { resetColor(); }
121