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     OS.enable_colors();
26 
27     switch (Color) {
28     case HighlightColor::Address:
29       OS.changeColor(raw_ostream::YELLOW);
30       break;
31     case HighlightColor::String:
32       OS.changeColor(raw_ostream::GREEN);
33       break;
34     case HighlightColor::Tag:
35       OS.changeColor(raw_ostream::BLUE);
36       break;
37     case HighlightColor::Attribute:
38       OS.changeColor(raw_ostream::CYAN);
39       break;
40     case HighlightColor::Enumerator:
41       OS.changeColor(raw_ostream::MAGENTA);
42       break;
43     case HighlightColor::Macro:
44       OS.changeColor(raw_ostream::RED);
45       break;
46     case HighlightColor::Error:
47       OS.changeColor(raw_ostream::RED, true);
48       break;
49     case HighlightColor::Warning:
50       OS.changeColor(raw_ostream::MAGENTA, true);
51       break;
52     case HighlightColor::Note:
53       OS.changeColor(raw_ostream::BLACK, true);
54       break;
55     case HighlightColor::Remark:
56       OS.changeColor(raw_ostream::BLUE, true);
57       break;
58     }
59   }
60 }
61 
62 raw_ostream &WithColor::error() { return error(errs()); }
63 
64 raw_ostream &WithColor::warning() { return warning(errs()); }
65 
66 raw_ostream &WithColor::note() { return note(errs()); }
67 
68 raw_ostream &WithColor::remark() { return remark(errs()); }
69 
70 raw_ostream &WithColor::error(raw_ostream &OS, StringRef Prefix,
71                               bool DisableColors) {
72   if (!Prefix.empty())
73     OS << Prefix << ": ";
74   return WithColor(OS, HighlightColor::Error, DisableColors).get()
75          << "error: ";
76 }
77 
78 raw_ostream &WithColor::warning(raw_ostream &OS, StringRef Prefix,
79                                 bool DisableColors) {
80   if (!Prefix.empty())
81     OS << Prefix << ": ";
82   return WithColor(OS, HighlightColor::Warning, DisableColors).get()
83          << "warning: ";
84 }
85 
86 raw_ostream &WithColor::note(raw_ostream &OS, StringRef Prefix,
87                              bool DisableColors) {
88   if (!Prefix.empty())
89     OS << Prefix << ": ";
90   return WithColor(OS, HighlightColor::Note, DisableColors).get() << "note: ";
91 }
92 
93 raw_ostream &WithColor::remark(raw_ostream &OS, StringRef Prefix,
94                                bool DisableColors) {
95   if (!Prefix.empty())
96     OS << Prefix << ": ";
97   return WithColor(OS, HighlightColor::Remark, DisableColors).get()
98          << "remark: ";
99 }
100 
101 bool WithColor::colorsEnabled() {
102   if (DisableColors)
103     return false;
104   if (UseColor == cl::BOU_UNSET)
105     return OS.has_colors();
106   return UseColor == cl::BOU_TRUE;
107 }
108 
109 WithColor &WithColor::changeColor(raw_ostream::Color C, bool Bold, bool BG) {
110   if (colorsEnabled())
111     OS.changeColor(C, Bold, BG);
112   return *this;
113 }
114 
115 WithColor &WithColor::resetColor() {
116   if (colorsEnabled())
117     OS.resetColor();
118   return *this;
119 }
120 
121 WithColor::~WithColor() { resetColor(); }
122