@@ -24,6 +24,14 @@ const char *column_colors_ansi[] = {
24
24
GIT_COLOR_RESET ,
25
25
};
26
26
27
+ enum {
28
+ COLOR_BACKGROUND_OFFSET = 10 ,
29
+ COLOR_FOREGROUND_ANSI = 30 ,
30
+ COLOR_FOREGROUND_RGB = 38 ,
31
+ COLOR_FOREGROUND_256 = 38 ,
32
+ COLOR_FOREGROUND_BRIGHT_ANSI = 90 ,
33
+ };
34
+
27
35
/* Ignore the RESET at the end when giving the size */
28
36
const int column_colors_ansi_max = ARRAY_SIZE (column_colors_ansi ) - 1 ;
29
37
@@ -61,15 +69,38 @@ static int get_hex_color(const char *in, unsigned char *out)
61
69
return 0 ;
62
70
}
63
71
64
- static int parse_color (struct color * out , const char * name , int len )
72
+ /*
73
+ * If an ANSI color is recognized in "name", fill "out" and return 0.
74
+ * Otherwise, leave out unchanged and return -1.
75
+ */
76
+ static int parse_ansi_color (struct color * out , const char * name , int len )
65
77
{
66
78
/* Positions in array must match ANSI color codes */
67
79
static const char * const color_names [] = {
68
80
"black" , "red" , "green" , "yellow" ,
69
81
"blue" , "magenta" , "cyan" , "white"
70
82
};
71
- char * end ;
72
83
int i ;
84
+ int color_offset = COLOR_FOREGROUND_ANSI ;
85
+
86
+ if (strncasecmp (name , "bright" , 6 ) == 0 ) {
87
+ color_offset = COLOR_FOREGROUND_BRIGHT_ANSI ;
88
+ name += 6 ;
89
+ len -= 6 ;
90
+ }
91
+ for (i = 0 ; i < ARRAY_SIZE (color_names ); i ++ ) {
92
+ if (match_word (name , len , color_names [i ])) {
93
+ out -> type = COLOR_ANSI ;
94
+ out -> value = i + color_offset ;
95
+ return 0 ;
96
+ }
97
+ }
98
+ return -1 ;
99
+ }
100
+
101
+ static int parse_color (struct color * out , const char * name , int len )
102
+ {
103
+ char * end ;
73
104
long val ;
74
105
75
106
/* First try the special word "normal"... */
@@ -89,12 +120,8 @@ static int parse_color(struct color *out, const char *name, int len)
89
120
}
90
121
91
122
/* Then pick from our human-readable color names... */
92
- for (i = 0 ; i < ARRAY_SIZE (color_names ); i ++ ) {
93
- if (match_word (name , len , color_names [i ])) {
94
- out -> type = COLOR_ANSI ;
95
- out -> value = i ;
96
- return 0 ;
97
- }
123
+ if (parse_ansi_color (out , name , len ) == 0 ) {
124
+ return 0 ;
98
125
}
99
126
100
127
/* And finally try a literal 256-color-mode number */
@@ -109,10 +136,15 @@ static int parse_color(struct color *out, const char *name, int len)
109
136
else if (val < 0 ) {
110
137
out -> type = COLOR_NORMAL ;
111
138
return 0 ;
112
- /* Rewrite low numbers as more-portable standard colors. */
139
+ /* Rewrite 0-7 as more-portable standard colors. */
113
140
} else if (val < 8 ) {
114
141
out -> type = COLOR_ANSI ;
115
- out -> value = val ;
142
+ out -> value = val + COLOR_FOREGROUND_ANSI ;
143
+ return 0 ;
144
+ /* Rewrite 8-15 as more-portable aixterm colors. */
145
+ } else if (val < 16 ) {
146
+ out -> type = COLOR_ANSI ;
147
+ out -> value = val - 8 + COLOR_FOREGROUND_BRIGHT_ANSI ;
116
148
return 0 ;
117
149
} else if (val < 256 ) {
118
150
out -> type = COLOR_256 ;
@@ -166,23 +198,26 @@ int color_parse(const char *value, char *dst)
166
198
* already have the ANSI escape code in it. "out" should have enough
167
199
* space in it to fit any color.
168
200
*/
169
- static char * color_output (char * out , int len , const struct color * c , char type )
201
+ static char * color_output (char * out , int len , const struct color * c , int background )
170
202
{
203
+ int offset = 0 ;
204
+
205
+ if (background )
206
+ offset = COLOR_BACKGROUND_OFFSET ;
171
207
switch (c -> type ) {
172
208
case COLOR_UNSPECIFIED :
173
209
case COLOR_NORMAL :
174
210
break ;
175
211
case COLOR_ANSI :
176
- if (len < 2 )
177
- BUG ("color parsing ran out of space" );
178
- * out ++ = type ;
179
- * out ++ = '0' + c -> value ;
212
+ out += xsnprintf (out , len , "%d" , c -> value + offset );
180
213
break ;
181
214
case COLOR_256 :
182
- out += xsnprintf (out , len , "%c8;5;%d" , type , c -> value );
215
+ out += xsnprintf (out , len , "%d;5;%d" , COLOR_FOREGROUND_256 + offset ,
216
+ c -> value );
183
217
break ;
184
218
case COLOR_RGB :
185
- out += xsnprintf (out , len , "%c8;2;%d;%d;%d" , type ,
219
+ out += xsnprintf (out , len , "%d;2;%d;%d;%d" ,
220
+ COLOR_FOREGROUND_RGB + offset ,
186
221
c -> red , c -> green , c -> blue );
187
222
break ;
188
223
}
@@ -279,14 +314,12 @@ int color_parse_mem(const char *value, int value_len, char *dst)
279
314
if (!color_empty (& fg )) {
280
315
if (sep ++ )
281
316
OUT (';' );
282
- /* foreground colors are all in the 3x range */
283
- dst = color_output (dst , end - dst , & fg , '3' );
317
+ dst = color_output (dst , end - dst , & fg , 0 );
284
318
}
285
319
if (!color_empty (& bg )) {
286
320
if (sep ++ )
287
321
OUT (';' );
288
- /* background colors are all in the 4x range */
289
- dst = color_output (dst , end - dst , & bg , '4' );
322
+ dst = color_output (dst , end - dst , & bg , 1 );
290
323
}
291
324
OUT ('m' );
292
325
}
0 commit comments