1 //===---------------------AnsiTerminal.h ------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 
11 
12 #define ANSI_FG_COLOR_BLACK         30
13 #define ANSI_FG_COLOR_RED           31
14 #define ANSI_FG_COLOR_GREEN         32
15 #define ANSI_FG_COLOR_YELLOW        33
16 #define ANSI_FG_COLOR_BLUE          34
17 #define ANSI_FG_COLOR_PURPLE        35
18 #define ANSI_FG_COLOR_CYAN          36
19 #define ANSI_FG_COLOR_WHITE         37
20 
21 #define ANSI_BG_COLOR_BLACK         40
22 #define ANSI_BG_COLOR_RED           41
23 #define ANSI_BG_COLOR_GREEN         42
24 #define ANSI_BG_COLOR_YELLOW        43
25 #define ANSI_BG_COLOR_BLUE          44
26 #define ANSI_BG_COLOR_PURPLE        45
27 #define ANSI_BG_COLOR_CYAN          46
28 #define ANSI_BG_COLOR_WHITE         47
29 
30 #define ANSI_SPECIAL_FRAMED         51
31 #define ANSI_SPECIAL_ENCIRCLED      52
32 
33 #define ANSI_CTRL_NORMAL            0
34 #define ANSI_CTRL_BOLD              1
35 #define ANSI_CTRL_FAINT             2
36 #define ANSI_CTRL_ITALIC            3
37 #define ANSI_CTRL_UNDERLINE         4
38 #define ANSI_CTRL_SLOW_BLINK        5
39 #define ANSI_CTRL_FAST_BLINK        6
40 #define ANSI_CTRL_IMAGE_NEGATIVE    7
41 #define ANSI_CTRL_CONCEAL           8
42 #define ANSI_CTRL_CROSSED_OUT       9
43 
44 #define ANSI_ESC_START          "\033["
45 #define ANSI_ESC_END            "m"
46 
47 #define ANSI_1_CTRL(ctrl1)          "\033["##ctrl1 ANSI_ESC_END
48 #define ANSI_2_CTRL(ctrl1,ctrl2)    "\033["##ctrl1";"##ctrl2 ANSI_ESC_END
49 
50 namespace lldb_utility {
51 
52     namespace ansi {
53         const char *k_escape_start	 = "\033[";
54         const char *k_escape_end	 = "m";
55 
56         const char *k_fg_black	     = "30";
57         const char *k_fg_red	     = "31";
58         const char *k_fg_green	     = "32";
59         const char *k_fg_yellow      = "33";
60         const char *k_fg_blue	     = "34";
61         const char *k_fg_purple      = "35";
62         const char *k_fg_cyan        = "36";
63         const char *k_fg_white	     = "37";
64 
65         const char *k_bg_black	     = "40";
66         const char *k_bg_red	     = "41";
67         const char *k_bg_green	     = "42";
68         const char *k_bg_yellow      = "43";
69         const char *k_bg_blue	     = "44";
70         const char *k_bg_purple      = "45";
71         const char *k_bg_cyan        = "46";
72         const char *k_bg_white	     = "47";
73 
74         const char *k_ctrl_normal	     = "0";
75         const char *k_ctrl_bold	         = "1";
76         const char *k_ctrl_faint	     = "2";
77         const char *k_ctrl_italic        = "3";
78         const char *k_ctrl_underline	 = "4";
79         const char *k_ctrl_slow_blink    = "5";
80         const char *k_ctrl_fast_blink    = "6";
81         const char *k_ctrl_negative	     = "7";
82         const char *k_ctrl_conceal	     = "8";
83         const char *k_ctrl_crossed_out	 = "9";
84 
85         inline std::string
86         FormatAnsiTerminalCodes(const char *format, bool do_color = true)
87         {
88             // Convert "${ansi.XXX}" tokens to ansi values or clear them if do_color is false.
89             static const struct
90             {
91                 const char *name;
92                 const char *value;
93             } g_color_tokens[] =
94             {
95         #define _TO_STR2(_val) #_val
96         #define _TO_STR(_val) _TO_STR2(_val)
97                 { "fg.black}",        ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK)      ANSI_ESC_END },
98                 { "fg.red}",          ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED)        ANSI_ESC_END },
99                 { "fg.green}",        ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN)      ANSI_ESC_END },
100                 { "fg.yellow}",       ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW)     ANSI_ESC_END },
101                 { "fg.blue}",         ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE)       ANSI_ESC_END },
102                 { "fg.purple}",       ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE)     ANSI_ESC_END },
103                 { "fg.cyan}",         ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN)       ANSI_ESC_END },
104                 { "fg.white}",        ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE)      ANSI_ESC_END },
105                 { "bg.black}",        ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK)      ANSI_ESC_END },
106                 { "bg.red}",          ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED)        ANSI_ESC_END },
107                 { "bg.green}",        ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN)      ANSI_ESC_END },
108                 { "bg.yellow}",       ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW)     ANSI_ESC_END },
109                 { "bg.blue}",         ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE)       ANSI_ESC_END },
110                 { "bg.purple}",       ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE)     ANSI_ESC_END },
111                 { "bg.cyan}",         ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN)       ANSI_ESC_END },
112                 { "bg.white}",        ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE)      ANSI_ESC_END },
113                 { "normal}",          ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL)         ANSI_ESC_END },
114                 { "bold}",            ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD)           ANSI_ESC_END },
115                 { "faint}",           ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT)          ANSI_ESC_END },
116                 { "italic}",          ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC)         ANSI_ESC_END },
117                 { "underline}",       ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE)      ANSI_ESC_END },
118                 { "slow-blink}",      ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK)     ANSI_ESC_END },
119                 { "fast-blink}",      ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK)     ANSI_ESC_END },
120                 { "negative}",        ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END },
121                 { "conceal}",         ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL)        ANSI_ESC_END },
122                 { "crossed-out}",     ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT)    ANSI_ESC_END },
123         #undef _TO_STR
124         #undef _TO_STR2
125             };
126             static const char tok_hdr[] = "${ansi.";
127 
128             std::string fmt;
129             for (const char *p = format; *p; ++p)
130             {
131                 const char *tok_start = strstr (p, tok_hdr);
132                 if (!tok_start)
133                 {
134                     fmt.append (p, strlen(p));
135                     break;
136                 }
137 
138                 fmt.append (p, tok_start - p);
139                 p = tok_start;
140 
141                 const char *tok_str = tok_start + sizeof(tok_hdr) - 1;
142                 for (size_t i = 0; i < sizeof(g_color_tokens) / sizeof(g_color_tokens[0]); ++i)
143                 {
144                     if (!strncmp (tok_str, g_color_tokens[i].name, strlen(g_color_tokens[i].name)))
145                     {
146                         if (do_color)
147                             fmt.append (g_color_tokens[i].value);
148                         p = tok_str + strlen (g_color_tokens[i].name) - 1;
149                         break;
150                     }
151                 }
152             }
153             return fmt;
154         }
155     }
156 }
157