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/Compiler.h"
13 #include "llvm/Support/raw_ostream.h"
14 
15 namespace llvm {
16 
17 class Error;
18 class StringRef;
19 
20 namespace cl {
21 class OptionCategory;
22 }
23 
24 extern cl::OptionCategory &getColorCategory();
25 
26 // Symbolic names for various syntax elements.
27 enum class HighlightColor {
28   Address,
29   String,
30   Tag,
31   Attribute,
32   Enumerator,
33   Macro,
34   Error,
35   Warning,
36   Note,
37   Remark
38 };
39 
40 enum class ColorMode {
41   /// Determine whether to use color based on the command line argument and the
42   /// raw_ostream.
43   Auto,
44   /// Enable colors. Because raw_ostream is the one implementing colors, this
45   /// has no effect if the stream does not support colors or has colors
46   /// disabled.
47   Enable,
48   /// Disable colors.
49   Disable,
50 };
51 
52 /// An RAII object that temporarily switches an output stream to a specific
53 /// color.
54 class WithColor {
55 public:
56   using AutoDetectFunctionType = bool (*)(const raw_ostream &OS);
57 
58   /// To be used like this: WithColor(OS, HighlightColor::String) << "text";
59   /// @param OS The output stream
60   /// @param S Symbolic name for syntax element to color
61   /// @param Mode Enable, disable or compute whether to use colors.
62   LLVM_CTOR_NODISCARD WithColor(raw_ostream &OS, HighlightColor S,
63                                 ColorMode Mode = ColorMode::Auto);
64   /// To be used like this: WithColor(OS, raw_ostream::BLACK) << "text";
65   /// @param OS The output stream
66   /// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
67   /// change only the bold attribute, and keep colors untouched
68   /// @param Bold Bold/brighter text, default false
69   /// @param BG If true, change the background, default: change foreground
70   /// @param Mode Enable, disable or compute whether to use colors.
71   LLVM_CTOR_NODISCARD WithColor(
72       raw_ostream &OS, raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR,
73       bool Bold = false, bool BG = false, ColorMode Mode = ColorMode::Auto)
OS(OS)74       : OS(OS), Mode(Mode) {
75     changeColor(Color, Bold, BG);
76   }
77   ~WithColor();
78 
get()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