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