lsとgrepの色の出し方

4-3.文字列置換

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。これが色が付く付かないの理由なのでしょうか。

つづく

コメント

タイトルとURLをコピーしました