1 //===- WithColor.h ----------------------------------------------*- C++ -*-===//
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 #ifndef LLVM_SUPPORT_WITHCOLOR_H
10 #define LLVM_SUPPORT_WITHCOLOR_H
11 
12 #include "llvm/Support/raw_ostream.h"
13 
14 namespace llvm {
15 
16 class Error;
17 class StringRef;
18 
19 namespace cl {
20 class OptionCategory;
21 }
22 
23 extern cl::OptionCategory &getColorCategory();
24 
25 // Symbolic names for various syntax elements.
26 enum class HighlightColor {
27   Address,
28   String,
29   Tag,
30   Attribute,
31   Enumerator,
32   Macro,
33   Error,
34   Warning,
35   Note,
36   Remark
37 };
38 
39 enum class ColorMode {
40   /// Determine whether to use color based on the command line argument and the
41   /// raw_ostream.
42   Auto,
43   /// Enable colors. Because raw_ostream is the one implementing colors, this
44   /// has no effect if the stream does not support colors or has colors
45   /// disabled.
46   Enable,
47   /// Disable colors.
48   Disable,
49 };
50 
51 /// An RAII object that temporarily switches an output stream to a specific
52 /// color.
53 class WithColor {
54 public:
55   using AutoDetectFunctionType = bool (*)(const raw_ostream &OS);
56 
57   /// To be used like this: WithColor(OS, HighlightColor::String) << "text";
58   /// @param OS The output stream
59   /// @param S Symbolic name for syntax element to color
60   /// @param Mode Enable, disable or compute whether to use colors.
61   WithColor(raw_ostream &OS, HighlightColor S,
62             ColorMode Mode = ColorMode::Auto);
63   /// To be used like this: WithColor(OS, raw_ostream::Black) << "text";
64   /// @param OS The output stream
65   /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
66   /// change only the bold attribute, and keep colors untouched
67   /// @param Bold Bold/brighter text, default false
68   /// @param BG If true, change the background, default: change foreground
69   /// @param Mode Enable, disable or compute whether to use colors.
70   WithColor(raw_ostream &OS,
71             raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR,
72             bool Bold = false, bool BG = false,
73             ColorMode Mode = ColorMode::Auto)
74       : OS(OS), Mode(Mode) {
75     changeColor(Color, Bold, BG);
76   }
77   ~WithColor();
78 
79   raw_ostream &get() { return OS; }
80   operator raw_ostream &() { return OS; }
81   template <typename T> WithColor &operator<<(T &O) {
82     OS << O;
83     return *this;
84   }
85   template <typename T> WithColor &operator<<(const T &O) {
86     OS << O;
87     return *this;
88   }
89 
90   /// Convenience method for printing "error: " to stderr.
91   static raw_ostream &error();
92   /// Convenience method for printing "warning: " to stderr.
93   static raw_ostream &warning();
94   /// Convenience method for printing "note: " to stderr.
95   static raw_ostream &note();
96   /// Convenience method for printing "remark: " to stderr.
97   static raw_ostream &remark();
98 
99   /// Convenience method for printing "error: " to the given stream.
100   static raw_ostream &error(raw_ostream &OS, StringRef Prefix = "",
101                             bool DisableColors = false);
102   /// Convenience method for printing "warning: " to the given stream.
103   static raw_ostream &warning(raw_ostream &OS, StringRef Prefix = "",
104                               bool DisableColors = false);
105   /// Convenience method for printing "note: " to the given stream.
106   static raw_ostream &note(raw_ostream &OS, StringRef Prefix = "",
107                            bool DisableColors = false);
108   /// Convenience method for printing "remark: " to the given stream.
109   static raw_ostream &remark(raw_ostream &OS, StringRef Prefix = "",
110                              bool DisableColors = false);
111 
112   /// Determine whether colors are displayed.
113   bool colorsEnabled();
114 
115   /// Change the color of text that will be output from this point forward.
116   /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
117   /// change only the bold attribute, and keep colors untouched
118   /// @param Bold Bold/brighter text, default false
119   /// @param BG If true, change the background, default: change foreground
120   WithColor &changeColor(raw_ostream::Colors Color, bool Bold = false,
121                          bool BG = false);
122 
123   /// Reset the colors to terminal defaults. Call this when you are done
124   /// outputting colored text, or before program exit.
125   WithColor &resetColor();
126 
127   /// Implement default handling for Error.
128   /// Print "error: " to stderr.
129   static void defaultErrorHandler(Error Err);
130 
131   /// Implement default handling for Warning.
132   /// Print "warning: " to stderr.
133   static void defaultWarningHandler(Error Warning);
134 
135   /// Retrieve the default color auto detection function.
136   static AutoDetectFunctionType defaultAutoDetectFunction();
137 
138   /// Change the global auto detection function.
139   static void
140   setAutoDetectFunction(AutoDetectFunctionType NewAutoDetectFunction);
141 
142 private:
143   raw_ostream &OS;
144   ColorMode Mode;
145 
146   static AutoDetectFunctionType AutoDetectFunction;
147 };
148 
149 } // end namespace llvm
150 
151 #endif // LLVM_SUPPORT_WITHCOLOR_H
152