続きです。
grepのprint_line_middleを読んでみます。
takk@deb9:~/src/grep-2.27/src$ cat -n grep.c | sed -ne '1151,1217p' 1151 static char * 1152 print_line_middle (char *beg, char *lim, 1153 const char *line_color, const char *match_color) 1154 { 1155 size_t match_size; 1156 size_t match_offset; 1157 char *cur; 1158 char *mid = NULL; 1159 char *b; 1160 1161 for (cur = beg; 1162 (cur < lim 1163 && ((match_offset = execute (beg, lim - beg, &match_size, cur)) 1164 != (size_t) -1)); 1165 cur = b + match_size) 1166 { 1167 b = beg + match_offset; 1168 1169 /* Avoid matching the empty line at the end of the buffer. */ 1170 if (b == lim) 1171 break; 1172 1173 /* Avoid hanging on grep --color "" foo */ 1174 if (match_size == 0) 1175 { 1176 /* Make minimal progress; there may be further non-empty matches. */ 1177 /* XXX - Could really advance by one whole multi-octet character. */ 1178 match_size = 1; 1179 if (!mid) 1180 mid = cur; 1181 } 1182 else 1183 { 1184 /* This function is called on a matching line only, 1185 but is it selected or rejected/context? */ 1186 if (only_matching) 1187 { 1188 char sep = out_invert ? SEP_CHAR_REJECTED : SEP_CHAR_SELECTED; 1189 if (! print_line_head (b, match_size, lim, sep)) 1190 return NULL; 1191 } 1192 else 1193 { 1194 pr_sgr_start (line_color); 1195 if (mid) 1196 { 1197 cur = mid; 1198 mid = NULL; 1199 } 1200 fwrite_errno (cur, 1, b - cur); 1201 } 1202 1203 pr_sgr_start_if (match_color); 1204 fwrite_errno (b, 1, match_size); 1205 pr_sgr_end_if (match_color); 1206 if (only_matching) 1207 putchar_errno (eolbyte); 1208 } 1209 } 1210 1211 if (only_matching) 1212 cur = lim; 1213 else if (mid) 1214 cur = mid; 1215 1216 return cur; 1217 } takk@deb9:~/src/grep-2.27/src$
前回のgrep時にも見つけた関数ですが、1203行目のpr_sgr_start_if、1206行目のpr_sgr_end_ifが色制御に関連してそうです。
それぞれ関数を確認してみます。
311 /* SGR utility functions. */ 312 static void 313 pr_sgr_start (char const *s) 314 { 315 if (*s) 316 print_start_colorize (sgr_start, s); 317 } 318 static void 319 pr_sgr_end (char const *s) 320 { 321 if (*s) 322 print_end_colorize (sgr_end); 323 }
sgr_startという引数と、s、つまりmatch_colorを渡している関数print_start_colorizeを読んでます。sgr_startが気になります。
すぐ上の行にありました。
308 static const char *sgr_start = "\33[%sm\33[K"; 309 static const char *sgr_end = "\33[m\33[K";
色つけのエスケープシーケンスですね。%sを使ってるところから、printfに渡す文字列かと思います。ということは、print_start_colorizeの正体は、printfですね。まあ、間違ってたとしても、困ることはないので、わざわざ見なくてもよいでしょう。
ということで、grep –colorで表示される色は、ただのエスケープシーケンスですね。
では何故、パイプで渡すと色が消えるのか。。。
つづく
コメント