1 //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #define ANSI_FG_COLOR_BLACK 30
10 #define ANSI_FG_COLOR_RED 31
11 #define ANSI_FG_COLOR_GREEN 32
12 #define ANSI_FG_COLOR_YELLOW 33
13 #define ANSI_FG_COLOR_BLUE 34
14 #define ANSI_FG_COLOR_PURPLE 35
15 #define ANSI_FG_COLOR_CYAN 36
16 #define ANSI_FG_COLOR_WHITE 37
18 #define ANSI_BG_COLOR_BLACK 40
19 #define ANSI_BG_COLOR_RED 41
20 #define ANSI_BG_COLOR_GREEN 42
21 #define ANSI_BG_COLOR_YELLOW 43
22 #define ANSI_BG_COLOR_BLUE 44
23 #define ANSI_BG_COLOR_PURPLE 45
24 #define ANSI_BG_COLOR_CYAN 46
25 #define ANSI_BG_COLOR_WHITE 47
27 #define ANSI_SPECIAL_FRAMED 51
28 #define ANSI_SPECIAL_ENCIRCLED 52
30 #define ANSI_CTRL_NORMAL 0
31 #define ANSI_CTRL_BOLD 1
32 #define ANSI_CTRL_FAINT 2
33 #define ANSI_CTRL_ITALIC 3
34 #define ANSI_CTRL_UNDERLINE 4
35 #define ANSI_CTRL_SLOW_BLINK 5
36 #define ANSI_CTRL_FAST_BLINK 6
37 #define ANSI_CTRL_IMAGE_NEGATIVE 7
38 #define ANSI_CTRL_CONCEAL 8
39 #define ANSI_CTRL_CROSSED_OUT 9
41 #define ANSI_ESC_START "\033["
42 #define ANSI_ESC_END "m"
44 #define ANSI_STR(s) #s
45 #define ANSI_DEF_STR(s) ANSI_STR(s)
47 #define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END
49 #define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
50 #define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END
52 #include "llvm/ADT/ArrayRef.h"
53 #include "llvm/ADT/STLExtras.h"
54 #include "llvm/ADT/StringRef.h"
58 namespace lldb_private {
62 inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
63 bool do_color = true) {
64 // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is
69 } g_color_tokens[] = {
70 #define _TO_STR2(_val) #_val
71 #define _TO_STR(_val) _TO_STR2(_val)
72 {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END},
73 {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END},
74 {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END},
75 {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END},
76 {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END},
77 {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END},
78 {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END},
79 {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END},
80 {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END},
81 {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END},
82 {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END},
83 {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END},
84 {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END},
85 {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END},
86 {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END},
87 {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END},
88 {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END},
89 {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END},
90 {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END},
91 {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END},
92 {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END},
94 ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END},
96 ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END},
98 ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END},
99 {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END},
101 ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END},
105 auto codes = llvm::makeArrayRef(g_color_tokens);
107 static const char tok_hdr[] = "${ansi.";
110 while (!format.empty()) {
111 llvm::StringRef left, right;
112 std::tie(left, right) = format.split(tok_hdr);
116 if (left == format && right.empty()) {
117 // The header was not found. Just exit.
121 bool found_code = false;
122 for (const auto &code : codes) {
123 if (!right.consume_front(code.name))
127 fmt.append(code.value);
132 // If we haven't found a valid replacement value, we just copy the string
133 // to the result without any modifications.
140 } // namespace lldb_private