続きです。
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で表示される色は、ただのエスケープシーケンスですね。
では何故、パイプで渡すと色が消えるのか。。。
つづく



コメント