Search code examples
linuxbashunixcolorsreadline

libreadline: When is the function "_rl_parse_colors()" called?


I am working on Bash 5.0 from GNU repository. I wanted to debug the functions that parse the colors so I went to the colors files:

  1. bash-5.0/lib/readline/colors.c - link
  2. bash-5.0/lib/readline/parse-colors.c - link

I added prints like that in the function _rl_parse_colors:

printf ("[*] INSIDE _rl_parse_colors");  

I did it almost in any function but after I compiled it, I ran it but it didn't print my debug prints:

root@ubuntu:~/Desktop/bash-5.0# ./bash -c 'echo -e "\033[31mHello\e[0m World"'
Hello World

I also tried to access the bash and then run it:

root@ubuntu:~/Desktop/bash-5.0# ./bash
root@ubuntu:~/Desktop/bash-5.0# echo $BASH_VERSION                                                         
5.0.0(8)-release
root@ubuntu:~/Desktop/bash-5.0# ./bash -c 'echo -e "\033[31mHello\e[0m World"'
Hello World

It print the "Hello" with red but not my prints.
Is it related to the fact that I am using echo? I don't see how it could affect because eventfully, the bash wraps the STDOUT of the command so it should draw the string with red.


Solution

  • Found the code (I'm on the bash-5.1-testing branch) --

    In file lib/readline/parse-colors.c:

    300 void _rl_parse_colors(void)
    301 {
    302 #if defined (COLOR_SUPPORT)
    303   const char *p;                /* Pointer to character being parsed */
    304   char *buf;                    /* color_buf buffer pointer */
    305   int state;                    /* State of parser */
    306   int ind_no;                   /* Indicator number */
    307   char label[3];                /* Indicator label */
    308   COLOR_EXT_TYPE *ext;          /* Extension we are working on */
    309
    310   p = sh_get_env_value ("LS_COLORS");
    311   if (p == 0 || *p == '\0')
    312     {
    313       _rl_color_ext_list = NULL;
    314       return;
    315     }
    ...
    

    There's only one call of _rl_parse_colors() in file lib/readline/readline.c:

    1215 /* Initialize the entire state of the world. */
    1216 static void
    1217 readline_initialize_everything (void)
    1218 {
    ....
    1287
    1288 #if defined (COLOR_SUPPORT)
    1289   if (_rl_colored_stats || _rl_colored_completion_prefix)
    1290     _rl_parse_colors ();
    1291 #endif
    1292
    

    The vars names _rl_colored_stats and _rl_colored_completion_prefix sound to be for these readline settings:

    [STEP 101] $ bind -v | grep color
    set colored-completion-prefix off
    set colored-stats off
    [STEP 102] $
    

    I just verified that these steps would enter _rl_parse_colors():

    1. Turn on colored-completion-prefix or colored-stats in ~/.inputrc.
    2. [optional] Set (and export) LS_COLORS
    3. Start an interactive shell with your compiled bash (./bash)

    According to bash manual (man bash):

    colored-completion-prefix (Off)

    If set to On, when listing completions, readline displays the common prefix of the set of possible completions using a different color. The color definitions are taken from the value of the LS_COLORS environment variable.

    colored-stats (Off)

    If set to On, readline displays possible completions using different colors to indicate their file type. The color definitions are taken from the value of the LS_COLORS environment variable.