AnsiTerminal.h revision 341825
1254721Semaste//===---------------------AnsiTerminal.h ------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10314564Sdim#define ANSI_FG_COLOR_BLACK 30 11314564Sdim#define ANSI_FG_COLOR_RED 31 12314564Sdim#define ANSI_FG_COLOR_GREEN 32 13314564Sdim#define ANSI_FG_COLOR_YELLOW 33 14314564Sdim#define ANSI_FG_COLOR_BLUE 34 15314564Sdim#define ANSI_FG_COLOR_PURPLE 35 16314564Sdim#define ANSI_FG_COLOR_CYAN 36 17314564Sdim#define ANSI_FG_COLOR_WHITE 37 18254721Semaste 19314564Sdim#define ANSI_BG_COLOR_BLACK 40 20314564Sdim#define ANSI_BG_COLOR_RED 41 21314564Sdim#define ANSI_BG_COLOR_GREEN 42 22314564Sdim#define ANSI_BG_COLOR_YELLOW 43 23314564Sdim#define ANSI_BG_COLOR_BLUE 44 24314564Sdim#define ANSI_BG_COLOR_PURPLE 45 25314564Sdim#define ANSI_BG_COLOR_CYAN 46 26314564Sdim#define ANSI_BG_COLOR_WHITE 47 27254721Semaste 28314564Sdim#define ANSI_SPECIAL_FRAMED 51 29314564Sdim#define ANSI_SPECIAL_ENCIRCLED 52 30254721Semaste 31314564Sdim#define ANSI_CTRL_NORMAL 0 32314564Sdim#define ANSI_CTRL_BOLD 1 33314564Sdim#define ANSI_CTRL_FAINT 2 34314564Sdim#define ANSI_CTRL_ITALIC 3 35314564Sdim#define ANSI_CTRL_UNDERLINE 4 36314564Sdim#define ANSI_CTRL_SLOW_BLINK 5 37314564Sdim#define ANSI_CTRL_FAST_BLINK 6 38314564Sdim#define ANSI_CTRL_IMAGE_NEGATIVE 7 39314564Sdim#define ANSI_CTRL_CONCEAL 8 40314564Sdim#define ANSI_CTRL_CROSSED_OUT 9 41254721Semaste 42314564Sdim#define ANSI_ESC_START "\033[" 43314564Sdim#define ANSI_ESC_END "m" 44254721Semaste 45314564Sdim#define ANSI_STR(s) #s 46314564Sdim#define ANSI_DEF_STR(s) ANSI_STR(s) 47254721Semaste 48314564Sdim#define ANSI_ESCAPE1(s) ANSI_ESC_START ANSI_DEF_STR(s) ANSI_ESC_END 49254721Semaste 50314564Sdim#define ANSI_1_CTRL(ctrl1) "\033["##ctrl1 ANSI_ESC_END 51314564Sdim#define ANSI_2_CTRL(ctrl1, ctrl2) "\033["##ctrl1 ";"##ctrl2 ANSI_ESC_END 52296417Sdim 53341825Sdim#include "llvm/ADT/ArrayRef.h" 54314564Sdim#include "llvm/ADT/STLExtras.h" 55314564Sdim#include "llvm/ADT/StringRef.h" 56296417Sdim 57314564Sdim#include <string> 58254721Semaste 59254721Semastenamespace lldb_utility { 60254721Semaste 61314564Sdimnamespace ansi { 62254721Semaste 63314564Sdiminline std::string FormatAnsiTerminalCodes(llvm::StringRef format, 64314564Sdim bool do_color = true) { 65314564Sdim // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is 66314564Sdim // false. 67314564Sdim static const struct { 68314564Sdim const char *name; 69314564Sdim const char *value; 70314564Sdim } g_color_tokens[] = { 71314564Sdim#define _TO_STR2(_val) #_val 72314564Sdim#define _TO_STR(_val) _TO_STR2(_val) 73314564Sdim {"fg.black}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END}, 74314564Sdim {"fg.red}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END}, 75314564Sdim {"fg.green}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END}, 76314564Sdim {"fg.yellow}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END}, 77314564Sdim {"fg.blue}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END}, 78314564Sdim {"fg.purple}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END}, 79314564Sdim {"fg.cyan}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END}, 80314564Sdim {"fg.white}", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END}, 81314564Sdim {"bg.black}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END}, 82314564Sdim {"bg.red}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END}, 83314564Sdim {"bg.green}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END}, 84314564Sdim {"bg.yellow}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END}, 85314564Sdim {"bg.blue}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END}, 86314564Sdim {"bg.purple}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END}, 87314564Sdim {"bg.cyan}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END}, 88314564Sdim {"bg.white}", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END}, 89314564Sdim {"normal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END}, 90314564Sdim {"bold}", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END}, 91314564Sdim {"faint}", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END}, 92314564Sdim {"italic}", ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END}, 93314564Sdim {"underline}", ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END}, 94314564Sdim {"slow-blink}", 95314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END}, 96314564Sdim {"fast-blink}", 97314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END}, 98314564Sdim {"negative}", 99314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END}, 100314564Sdim {"conceal}", ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END}, 101314564Sdim {"crossed-out}", 102314564Sdim ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END}, 103314564Sdim#undef _TO_STR 104314564Sdim#undef _TO_STR2 105314564Sdim }; 106314564Sdim auto codes = llvm::makeArrayRef(g_color_tokens); 107254721Semaste 108314564Sdim static const char tok_hdr[] = "${ansi."; 109254721Semaste 110314564Sdim std::string fmt; 111314564Sdim while (!format.empty()) { 112314564Sdim llvm::StringRef left, right; 113314564Sdim std::tie(left, right) = format.split(tok_hdr); 114254721Semaste 115314564Sdim fmt.append(left); 116314564Sdim 117314564Sdim if (left == format && right.empty()) { 118314564Sdim // The header was not found. Just exit. 119314564Sdim break; 120254721Semaste } 121314564Sdim 122341825Sdim bool found_code = false; 123314564Sdim for (const auto &code : codes) { 124314564Sdim if (!right.consume_front(code.name)) 125314564Sdim continue; 126314564Sdim 127314564Sdim if (do_color) 128314564Sdim fmt.append(code.value); 129341825Sdim found_code = true; 130314564Sdim break; 131314564Sdim } 132341825Sdim format = right; 133341825Sdim // If we haven't found a valid replacement value, we just copy the string 134341825Sdim // to the result without any modifications. 135341825Sdim if (!found_code) 136341825Sdim fmt.append(tok_hdr); 137314564Sdim } 138314564Sdim return fmt; 139254721Semaste} 140314564Sdim} 141314564Sdim} 142