1254721Semaste//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9314564Sdim#define ANSI_FG_COLOR_BLACK 30 10314564Sdim#define ANSI_FG_COLOR_RED 31 11314564Sdim#define ANSI_FG_COLOR_GREEN 32 12314564Sdim#define ANSI_FG_COLOR_YELLOW 33 13314564Sdim#define ANSI_FG_COLOR_BLUE 34 14314564Sdim#define ANSI_FG_COLOR_PURPLE 35 15314564Sdim#define ANSI_FG_COLOR_CYAN 36 16314564Sdim#define ANSI_FG_COLOR_WHITE 37 17254721Semaste 18314564Sdim#define ANSI_BG_COLOR_BLACK 40 19314564Sdim#define ANSI_BG_COLOR_RED 41 20314564Sdim#define ANSI_BG_COLOR_GREEN 42 21314564Sdim#define ANSI_BG_COLOR_YELLOW 43 22314564Sdim#define ANSI_BG_COLOR_BLUE 44 23314564Sdim#define ANSI_BG_COLOR_PURPLE 45 24314564Sdim#define ANSI_BG_COLOR_CYAN 46 25314564Sdim#define ANSI_BG_COLOR_WHITE 47 26254721Semaste 27314564Sdim#define ANSI_SPECIAL_FRAMED 51 28314564Sdim#define ANSI_SPECIAL_ENCIRCLED 52 29254721Semaste 30314564Sdim#define ANSI_CTRL_NORMAL 0 31314564Sdim#define ANSI_CTRL_BOLD 1 32314564Sdim#define ANSI_CTRL_FAINT 2 33314564Sdim#define ANSI_CTRL_ITALIC 3 34314564Sdim#define ANSI_CTRL_UNDERLINE 4 35314564Sdim#define ANSI_CTRL_SLOW_BLINK 5 36314564Sdim#define ANSI_CTRL_FAST_BLINK 6 37314564Sdim#define ANSI_CTRL_IMAGE_NEGATIVE 7 38314564Sdim#define ANSI_CTRL_CONCEAL 8 39314564Sdim#define ANSI_CTRL_CROSSED_OUT 9 40254721Semaste 41314564Sdim#define ANSI_ESC_START "\033[" 42314564Sdim#define ANSI_ESC_END "m" 43254721Semaste 44314564Sdim#define ANSI_STR(s) #s 45314564Sdim#define ANSI_DEF_STR(s) ANSI_STR(s) 46254721Semaste 47314564Sdim#define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END 48254721Semaste 49314564Sdim#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END 50314564Sdim#define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END 51296417Sdim 52341825Sdim#include "llvm/ADT/ArrayRef.h" 53314564Sdim#include "llvm/ADT/STLExtras.h" 54314564Sdim#include "llvm/ADT/StringRef.h" 55296417Sdim 56314564Sdim#include <string> 57254721Semaste 58360784Sdimnamespace lldb_private { 59254721Semaste 60314564Sdimnamespace ansi { 61254721Semaste 62314564Sdiminline std::string FormatAnsiTerminalCodes(llvm::StringRef format, 63314564Sdim bool do_color = true) { 64314564Sdim // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is 65314564Sdim // false. 66314564Sdim static const struct { 67314564Sdim const char *name; 68314564Sdim const char *value; 69314564Sdim } g_color_tokens[] = { 70314564Sdim#define _TO_STR2(_val) #_val 71314564Sdim#define _TO_STR(_val) _TO_STR2(_val) 72314564Sdim {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END}, 73314564Sdim {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END}, 74314564Sdim {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END}, 75314564Sdim {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END}, 76314564Sdim {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END}, 77314564Sdim {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END}, 78314564Sdim {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END}, 79314564Sdim {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END}, 80314564Sdim {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END}, 81314564Sdim {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END}, 82314564Sdim {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END}, 83314564Sdim {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END}, 84314564Sdim {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END}, 85314564Sdim {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END}, 86314564Sdim {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END}, 87314564Sdim {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END}, 88314564Sdim {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END}, 89314564Sdim {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END}, 90314564Sdim {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END}, 91314564Sdim {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END}, 92314564Sdim {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END}, 93314564Sdim {"slow-blink}", 94314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END}, 95314564Sdim {"fast-blink}", 96314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END}, 97314564Sdim {"negative}", 98314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END}, 99314564Sdim {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END}, 100314564Sdim {"crossed-out}", 101314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END}, 102314564Sdim#undef _TO_STR 103314564Sdim#undef _TO_STR2 104314564Sdim }; 105314564Sdim auto codes = llvm::makeArrayRef(g_color_tokens); 106254721Semaste 107314564Sdim static const char tok_hdr[] = "${ansi."; 108254721Semaste 109314564Sdim std::string fmt; 110314564Sdim while (!format.empty()) { 111314564Sdim llvm::StringRef left, right; 112314564Sdim std::tie(left, right) = format.split(tok_hdr); 113254721Semaste 114314564Sdim fmt.append(left); 115314564Sdim 116314564Sdim if (left == format && right.empty()) { 117314564Sdim // The header was not found. Just exit. 118314564Sdim break; 119254721Semaste } 120314564Sdim 121341825Sdim bool found_code = false; 122314564Sdim for (const auto &code : codes) { 123314564Sdim if (!right.consume_front(code.name)) 124314564Sdim continue; 125314564Sdim 126314564Sdim if (do_color) 127314564Sdim fmt.append(code.value); 128341825Sdim found_code = true; 129314564Sdim break; 130314564Sdim } 131341825Sdim format = right; 132341825Sdim // If we haven't found a valid replacement value, we just copy the string 133341825Sdim // to the result without any modifications. 134341825Sdim if (!found_code) 135341825Sdim fmt.append(tok_hdr); 136314564Sdim } 137314564Sdim return fmt; 138254721Semaste} 139314564Sdim} 140360784Sdim} // namespace lldb_private 141