xref: /freebsd-src/contrib/llvm-project/lldb/include/lldb/Utility/AnsiTerminal.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
981ad6265SDimitry Andric #ifndef LLDB_UTILITY_ANSITERMINAL_H
1081ad6265SDimitry Andric #define LLDB_UTILITY_ANSITERMINAL_H
1181ad6265SDimitry Andric 
120b57cec5SDimitry Andric #define ANSI_FG_COLOR_BLACK 30
130b57cec5SDimitry Andric #define ANSI_FG_COLOR_RED 31
140b57cec5SDimitry Andric #define ANSI_FG_COLOR_GREEN 32
150b57cec5SDimitry Andric #define ANSI_FG_COLOR_YELLOW 33
160b57cec5SDimitry Andric #define ANSI_FG_COLOR_BLUE 34
170b57cec5SDimitry Andric #define ANSI_FG_COLOR_PURPLE 35
180b57cec5SDimitry Andric #define ANSI_FG_COLOR_CYAN 36
190b57cec5SDimitry Andric #define ANSI_FG_COLOR_WHITE 37
200b57cec5SDimitry Andric 
2181ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_BLACK 90
2281ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_RED 91
2381ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_GREEN 92
2481ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_YELLOW 93
2581ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_BLUE 94
2681ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_PURPLE 95
2781ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_CYAN 96
2881ad6265SDimitry Andric #define ANSI_FG_COLOR_BRIGHT_WHITE 97
2981ad6265SDimitry Andric 
300b57cec5SDimitry Andric #define ANSI_BG_COLOR_BLACK 40
310b57cec5SDimitry Andric #define ANSI_BG_COLOR_RED 41
320b57cec5SDimitry Andric #define ANSI_BG_COLOR_GREEN 42
330b57cec5SDimitry Andric #define ANSI_BG_COLOR_YELLOW 43
340b57cec5SDimitry Andric #define ANSI_BG_COLOR_BLUE 44
350b57cec5SDimitry Andric #define ANSI_BG_COLOR_PURPLE 45
360b57cec5SDimitry Andric #define ANSI_BG_COLOR_CYAN 46
370b57cec5SDimitry Andric #define ANSI_BG_COLOR_WHITE 47
380b57cec5SDimitry Andric 
3981ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_BLACK 100
4081ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_RED 101
4181ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_GREEN 102
4281ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_YELLOW 103
4381ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_BLUE 104
4481ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_PURPLE 105
4581ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_CYAN 106
4681ad6265SDimitry Andric #define ANSI_BG_COLOR_BRIGHT_WHITE 107
4781ad6265SDimitry Andric 
480b57cec5SDimitry Andric #define ANSI_SPECIAL_FRAMED 51
490b57cec5SDimitry Andric #define ANSI_SPECIAL_ENCIRCLED 52
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric #define ANSI_CTRL_NORMAL 0
520b57cec5SDimitry Andric #define ANSI_CTRL_BOLD 1
530b57cec5SDimitry Andric #define ANSI_CTRL_FAINT 2
540b57cec5SDimitry Andric #define ANSI_CTRL_ITALIC 3
550b57cec5SDimitry Andric #define ANSI_CTRL_UNDERLINE 4
560b57cec5SDimitry Andric #define ANSI_CTRL_SLOW_BLINK 5
570b57cec5SDimitry Andric #define ANSI_CTRL_FAST_BLINK 6
580b57cec5SDimitry Andric #define ANSI_CTRL_IMAGE_NEGATIVE 7
590b57cec5SDimitry Andric #define ANSI_CTRL_CONCEAL 8
600b57cec5SDimitry Andric #define ANSI_CTRL_CROSSED_OUT 9
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric #define ANSI_ESC_START "\033["
630b57cec5SDimitry Andric #define ANSI_ESC_END "m"
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric #define ANSI_STR(s) #s
660b57cec5SDimitry Andric #define ANSI_DEF_STR(s) ANSI_STR(s)
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric #define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric #define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END
710b57cec5SDimitry Andric #define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
740b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
750b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric #include <string>
780b57cec5SDimitry Andric 
799dba64beSDimitry Andric namespace lldb_private {
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric namespace ansi {
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric inline std::string FormatAnsiTerminalCodes(llvm::StringRef format,
840b57cec5SDimitry Andric                                            bool do_color = true) {
850b57cec5SDimitry Andric   // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is
860b57cec5SDimitry Andric   // false.
8781ad6265SDimitry Andric   // clang-format off
880b57cec5SDimitry Andric   static const struct {
890b57cec5SDimitry Andric     const char *name;
900b57cec5SDimitry Andric     const char *value;
910b57cec5SDimitry Andric   } g_color_tokens[] = {
920b57cec5SDimitry Andric #define _TO_STR2(_val) #_val
930b57cec5SDimitry Andric #define _TO_STR(_val) _TO_STR2(_val)
940b57cec5SDimitry Andric       {"fg.black}",         ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END},
950b57cec5SDimitry Andric       {"fg.red}",           ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END},
960b57cec5SDimitry Andric       {"fg.green}",         ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END},
970b57cec5SDimitry Andric       {"fg.yellow}",        ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END},
980b57cec5SDimitry Andric       {"fg.blue}",          ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END},
990b57cec5SDimitry Andric       {"fg.purple}",        ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END},
1000b57cec5SDimitry Andric       {"fg.cyan}",          ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END},
1010b57cec5SDimitry Andric       {"fg.white}",         ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END},
10281ad6265SDimitry Andric       {"fg.bright.black}",  ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLACK) ANSI_ESC_END},
10381ad6265SDimitry Andric       {"fg.bright.red}",    ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_RED) ANSI_ESC_END},
10481ad6265SDimitry Andric       {"fg.bright.green}",  ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_GREEN) ANSI_ESC_END},
10581ad6265SDimitry Andric       {"fg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END},
10681ad6265SDimitry Andric       {"fg.bright.blue}",   ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_BLUE) ANSI_ESC_END},
10781ad6265SDimitry Andric       {"fg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END},
10881ad6265SDimitry Andric       {"fg.bright.cyan}",   ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_CYAN) ANSI_ESC_END},
10981ad6265SDimitry Andric       {"fg.bright.white}",  ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BRIGHT_WHITE) ANSI_ESC_END},
1100b57cec5SDimitry Andric       {"bg.black}",         ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END},
1110b57cec5SDimitry Andric       {"bg.red}",           ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END},
1120b57cec5SDimitry Andric       {"bg.green}",         ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END},
1130b57cec5SDimitry Andric       {"bg.yellow}",        ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END},
1140b57cec5SDimitry Andric       {"bg.blue}",          ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END},
1150b57cec5SDimitry Andric       {"bg.purple}",        ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END},
1160b57cec5SDimitry Andric       {"bg.cyan}",          ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END},
1170b57cec5SDimitry Andric       {"bg.white}",         ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END},
11881ad6265SDimitry Andric       {"bg.bright.black}",  ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLACK) ANSI_ESC_END},
11981ad6265SDimitry Andric       {"bg.bright.red}",    ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_RED) ANSI_ESC_END},
12081ad6265SDimitry Andric       {"bg.bright.green}",  ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_GREEN) ANSI_ESC_END},
12181ad6265SDimitry Andric       {"bg.bright.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_YELLOW) ANSI_ESC_END},
12281ad6265SDimitry Andric       {"bg.bright.blue}",   ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_BLUE) ANSI_ESC_END},
12381ad6265SDimitry Andric       {"bg.bright.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_PURPLE) ANSI_ESC_END},
12481ad6265SDimitry Andric       {"bg.bright.cyan}",   ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_CYAN) ANSI_ESC_END},
12581ad6265SDimitry Andric       {"bg.bright.white}",  ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BRIGHT_WHITE) ANSI_ESC_END},
1260b57cec5SDimitry Andric       {"normal}",           ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END},
1270b57cec5SDimitry Andric       {"bold}",             ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END},
1280b57cec5SDimitry Andric       {"faint}",            ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END},
1290b57cec5SDimitry Andric       {"italic}",           ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END},
1300b57cec5SDimitry Andric       {"underline}",        ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END},
13181ad6265SDimitry Andric       {"slow-blink}",       ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END},
13281ad6265SDimitry Andric       {"fast-blink}",       ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END},
13381ad6265SDimitry Andric       {"negative}",         ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END},
1340b57cec5SDimitry Andric       {"conceal}",          ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END},
13581ad6265SDimitry Andric       {"crossed-out}",      ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END},
1360b57cec5SDimitry Andric #undef _TO_STR
1370b57cec5SDimitry Andric #undef _TO_STR2
1380b57cec5SDimitry Andric   };
13981ad6265SDimitry Andric   // clang-format on
140*bdd1243dSDimitry Andric   auto codes = llvm::ArrayRef(g_color_tokens);
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   static const char tok_hdr[] = "${ansi.";
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   std::string fmt;
1450b57cec5SDimitry Andric   while (!format.empty()) {
1460b57cec5SDimitry Andric     llvm::StringRef left, right;
1470b57cec5SDimitry Andric     std::tie(left, right) = format.split(tok_hdr);
1480b57cec5SDimitry Andric 
1495ffd83dbSDimitry Andric     fmt += left;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric     if (left == format && right.empty()) {
1520b57cec5SDimitry Andric       // The header was not found.  Just exit.
1530b57cec5SDimitry Andric       break;
1540b57cec5SDimitry Andric     }
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     bool found_code = false;
1570b57cec5SDimitry Andric     for (const auto &code : codes) {
1580b57cec5SDimitry Andric       if (!right.consume_front(code.name))
1590b57cec5SDimitry Andric         continue;
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric       if (do_color)
1620b57cec5SDimitry Andric         fmt.append(code.value);
1630b57cec5SDimitry Andric       found_code = true;
1640b57cec5SDimitry Andric       break;
1650b57cec5SDimitry Andric     }
1660b57cec5SDimitry Andric     format = right;
1670b57cec5SDimitry Andric     // If we haven't found a valid replacement value, we just copy the string
1680b57cec5SDimitry Andric     // to the result without any modifications.
1690b57cec5SDimitry Andric     if (!found_code)
1700b57cec5SDimitry Andric       fmt.append(tok_hdr);
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric   return fmt;
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric }
1759dba64beSDimitry Andric } // namespace lldb_private
1765ffd83dbSDimitry Andric 
1775ffd83dbSDimitry Andric #endif
178