「lsのパイプ後も色が付く」の続きです。
color_indicatorの使用箇所を検索します。
takk@deb9:~/src/coreutils-8.26/src$ grep color_indicator ls.c
static const struct bin_str * get_color_indicator (const struct fileinfo *f,
static bool print_color_indicator (const struct bin_str *ind);
static struct bin_str color_indicator[] =
size_t len = color_indicator[type].len;
char const *s = color_indicator[type].string;
put_indicator (&color_indicator[C_LEFT]);
put_indicator (&color_indicator[C_RIGHT]);
put_indicator (&color_indicator[C_LEFT]);
put_indicator (&color_indicator[C_NORM]);
put_indicator (&color_indicator[C_RIGHT]);
assert (ARRAY_CARDINALITY (color_indicator) + 1
if (!(color_indicator[C_LEFT].len == 2
&& memcmp (color_indicator[C_LEFT].string, "\033[", 2) == 0
&& color_indicator[C_RIGHT].len == 1
&& color_indicator[C_RIGHT].string[0] == 'm'))
color_indicator[ind_no].string = buf;
&color_indicator[ind_no].len)
if (color_indicator[C_LINK].len == 6
&& !STRNCMP_LIT (color_indicator[C_LINK].string, "target"))
print_color_indicator (color);
get_color_indicator (f, symlink_target) : NULL;
put_indicator (&color_indicator[C_CLR_TO_EOL]);
if (color_indicator[C_END].string != NULL)
put_indicator (&color_indicator[C_END]);
put_indicator (&color_indicator[C_LEFT]);
put_indicator (&color_indicator[C_RESET]);
put_indicator (&color_indicator[C_RIGHT]);
print_color_indicator (const struct bin_str *ind)
put_indicator (&color_indicator[C_LEFT]);
put_indicator (&color_indicator[C_RIGHT]);
get_color_indicator (const struct fileinfo *f, bool symlink_target)
= ext ? &(ext->seq) : &color_indicator[type];
takk@deb9:~/src/coreutils-8.26/src$
いろんな所で使われています。怪しいところは。。。
put_indicatorって関数でcolor_indicatorを使ってますね。put_indicatorを見てみることにします。
ls.c
4665 static void
4666 put_indicator (const struct bin_str *ind)
4667 {
4668 if (! used_color)
4669 {
4670 used_color = true;
4671
4672 /* If the standard output is a controlling terminal, watch out
4673 for signals, so that the colors can be restored to the
4674 default state if "ls" is suspended or interrupted. */
4675
4676 if (0 <= tcgetpgrp (STDOUT_FILENO))
4677 signal_init ();
4678
4679 prep_non_filename_text ();
4680 }
4681
4682 fwrite (ind->string, ind->len, 1, stdout);
4683 }
途中のコメントが興味深いですが、ここで確認するのは、fwriteを使ってるってところです。つまりlsで色(エスケープシーケンス)を出力する場合は、fwriteを使う、で良いかと思います。
対してgrepはどうだったかというと。。。。
ああ、そういえば、grepが本当にprintfを使っていたかは未確認でした。
引数に%sを与えてることからしてprintfを使ってるだろうと推測していましたが、一応確認してみましょう。
grep.c
308 static const char *sgr_start = "\33[%sm\33[K";
309 static const char *sgr_end = "\33[m\33[K";
310
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 }
print_start_colorizeを検索。
takk@deb9:~/src/grep-2.27$ grep print_start_colorize -r * ChangeLog: print_start_colorize, print_end_colorize from colorize.h. lib/colorize.h:extern void print_start_colorize (char const *sgr_start, char const *sgr_seq); lib/colorize-posix.c:print_start_colorize (char const *sgr_start, char const *sgr_seq) lib/colorize-w32.c:print_start_colorize (char const *sgr_start, char const *sgr_seq) src/grep.c: print_start_colorize (sgr_start, s); takk@deb9:~/src/grep-2.27$
lib/colorize-posix.cを確認。
45 /* Start a colorized text attribute on stdout using the SGR_START
46 format; the attribute is specified by SGR_SEQ. */
47 void
48 print_start_colorize (char const *sgr_start, char const *sgr_seq)
49 {
50 printf (sgr_start, sgr_seq);
51 }
予想通りprintfでした。
lsは、fwrite。grepはprintf。これが色が付く付かないの理由なのでしょうか。
つづく



コメント