@@ -26,30 +26,14 @@ enum color_diff {
26
26
DIFF_FILE_NEW = 5 ,
27
27
};
28
28
29
- #define COLOR_NORMAL ""
30
- #define COLOR_BOLD "\033[1m"
31
- #define COLOR_DIM "\033[2m"
32
- #define COLOR_UL "\033[4m"
33
- #define COLOR_BLINK "\033[5m"
34
- #define COLOR_REVERSE "\033[7m"
35
- #define COLOR_RESET "\033[m"
36
-
37
- #define COLOR_BLACK "\033[30m"
38
- #define COLOR_RED "\033[31m"
39
- #define COLOR_GREEN "\033[32m"
40
- #define COLOR_YELLOW "\033[33m"
41
- #define COLOR_BLUE "\033[34m"
42
- #define COLOR_MAGENTA "\033[35m"
43
- #define COLOR_CYAN "\033[36m"
44
- #define COLOR_WHITE "\033[37m"
45
-
46
- static const char * diff_colors [] = {
47
- COLOR_RESET ,
48
- COLOR_NORMAL ,
49
- COLOR_BOLD ,
50
- COLOR_CYAN ,
51
- COLOR_RED ,
52
- COLOR_GREEN
29
+ /* "\033[1;30;47m\0" is 11 bytes */
30
+ static char diff_colors [][16 ] = {
31
+ "\033[m" , /* reset */
32
+ "" , /* normal */
33
+ "\033[1m" , /* bold */
34
+ "\033[36m" , /* cyan */
35
+ "\033[31m" , /* red */
36
+ "\033[32m" /* green */
53
37
};
54
38
55
39
static int parse_diff_color_slot (const char * var , int ofs )
@@ -67,38 +51,104 @@ static int parse_diff_color_slot(const char *var, int ofs)
67
51
die ("bad config variable '%s'" , var );
68
52
}
69
53
70
- static const char * parse_diff_color_value (const char * value , const char * var )
71
- {
72
- if (!strcasecmp (value , "normal" ))
73
- return COLOR_NORMAL ;
74
- if (!strcasecmp (value , "bold" ))
75
- return COLOR_BOLD ;
76
- if (!strcasecmp (value , "dim" ))
77
- return COLOR_DIM ;
78
- if (!strcasecmp (value , "ul" ))
79
- return COLOR_UL ;
80
- if (!strcasecmp (value , "blink" ))
81
- return COLOR_BLINK ;
82
- if (!strcasecmp (value , "reverse" ))
83
- return COLOR_REVERSE ;
84
- if (!strcasecmp (value , "reset" ))
85
- return COLOR_RESET ;
86
- if (!strcasecmp (value , "black" ))
87
- return COLOR_BLACK ;
88
- if (!strcasecmp (value , "red" ))
89
- return COLOR_RED ;
90
- if (!strcasecmp (value , "green" ))
91
- return COLOR_GREEN ;
92
- if (!strcasecmp (value , "yellow" ))
93
- return COLOR_YELLOW ;
94
- if (!strcasecmp (value , "blue" ))
95
- return COLOR_BLUE ;
96
- if (!strcasecmp (value , "magenta" ))
97
- return COLOR_MAGENTA ;
98
- if (!strcasecmp (value , "cyan" ))
99
- return COLOR_CYAN ;
100
- if (!strcasecmp (value , "white" ))
101
- return COLOR_WHITE ;
54
+ static int parse_color (const char * name , int len )
55
+ {
56
+ static const char * const color_names [] = {
57
+ "normal" , "black" , "red" , "green" , "yellow" ,
58
+ "blue" , "magenta" , "cyan" , "white"
59
+ };
60
+ int i ;
61
+ for (i = 0 ; i < ARRAY_SIZE (color_names ); i ++ ) {
62
+ const char * str = color_names [i ];
63
+ if (!strncasecmp (name , str , len ) && !str [len ])
64
+ return i - 1 ;
65
+ }
66
+ return -2 ;
67
+ }
68
+
69
+ static int parse_attr (const char * name , int len )
70
+ {
71
+ static const int attr_values [] = { 1 , 2 , 4 , 5 , 7 };
72
+ static const char * const attr_names [] = {
73
+ "bold" , "dim" , "ul" , "blink" , "reverse"
74
+ };
75
+ int i ;
76
+ for (i = 0 ; i < ARRAY_SIZE (attr_names ); i ++ ) {
77
+ const char * str = attr_names [i ];
78
+ if (!strncasecmp (name , str , len ) && !str [len ])
79
+ return attr_values [i ];
80
+ }
81
+ return -1 ;
82
+ }
83
+
84
+ static void parse_diff_color_value (const char * value , const char * var , char * dst )
85
+ {
86
+ const char * ptr = value ;
87
+ int attr = -1 ;
88
+ int fg = -2 ;
89
+ int bg = -2 ;
90
+
91
+ if (!strcasecmp (value , "reset" )) {
92
+ strcpy (dst , "\033[m" );
93
+ return ;
94
+ }
95
+
96
+ /* [fg [bg]] [attr] */
97
+ while (* ptr ) {
98
+ const char * word = ptr ;
99
+ int val , len = 0 ;
100
+
101
+ while (word [len ] && !isspace (word [len ]))
102
+ len ++ ;
103
+
104
+ ptr = word + len ;
105
+ while (* ptr && isspace (* ptr ))
106
+ ptr ++ ;
107
+
108
+ val = parse_color (word , len );
109
+ if (val >= -1 ) {
110
+ if (fg == -2 ) {
111
+ fg = val ;
112
+ continue ;
113
+ }
114
+ if (bg == -2 ) {
115
+ bg = val ;
116
+ continue ;
117
+ }
118
+ goto bad ;
119
+ }
120
+ val = parse_attr (word , len );
121
+ if (val < 0 || attr != -1 )
122
+ goto bad ;
123
+ attr = val ;
124
+ }
125
+
126
+ if (attr >= 0 || fg >= 0 || bg >= 0 ) {
127
+ int sep = 0 ;
128
+
129
+ * dst ++ = '\033' ;
130
+ * dst ++ = '[' ;
131
+ if (attr >= 0 ) {
132
+ * dst ++ = '0' + attr ;
133
+ sep ++ ;
134
+ }
135
+ if (fg >= 0 ) {
136
+ if (sep ++ )
137
+ * dst ++ = ';' ;
138
+ * dst ++ = '3' ;
139
+ * dst ++ = '0' + fg ;
140
+ }
141
+ if (bg >= 0 ) {
142
+ if (sep ++ )
143
+ * dst ++ = ';' ;
144
+ * dst ++ = '4' ;
145
+ * dst ++ = '0' + bg ;
146
+ }
147
+ * dst ++ = 'm' ;
148
+ }
149
+ * dst = 0 ;
150
+ return ;
151
+ bad :
102
152
die ("bad config value '%s' for variable '%s'" , value , var );
103
153
}
104
154
@@ -145,7 +195,7 @@ int git_diff_ui_config(const char *var, const char *value)
145
195
}
146
196
if (!strncmp (var , "diff.color." , 11 )) {
147
197
int slot = parse_diff_color_slot (var , 11 );
148
- diff_colors [ slot ] = parse_diff_color_value (value , var );
198
+ parse_diff_color_value (value , var , diff_colors [ slot ] );
149
199
return 0 ;
150
200
}
151
201
return git_default_config (var , value );
0 commit comments