bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lib/readline/display.c and invisible characters


From: Edward Catmur
Subject: lib/readline/display.c and invisible characters
Date: Tue, 06 Jan 2004 01:25:52 +0000

Hi, I've been looking at the readline code for invisible characters in
PS1. 

I think the code at 550 in lib/readline/display.c is buggy: 

      temp = ((newlines + 1) * _rl_screenwidth) +
             ((newlines == 0 && local_prompt_prefix == 0) ?
prompt_invis_chars_first_line : 0) +
             ((newlines == 1) ? wrap_offset : 0);

should be

      temp = ((newlines + 1) * _rl_screenwidth) +
             ((local_prompt_prefix == 0)
              ? ((newlines == 0) ? prompt_invis_chars_first_line
                      : ((newlines == 1) ? wrap_offset : 0))
              : ((newlines == 0) ? wrap_offset : 0));

The original code gives the wrong logic when local_prompt_prefix is set,
as it gives an additional value of 0 when newlines == 0 and wrap_offset
when newlines == 1; these should be the other way round.

This gives incorrect behaviour e.g. when PS1 contains a newline followed
by invisible characters before a line break:

$ PS1='\n'$(perl -we 'print "=" x 76')'\[\033[00m\]*_*_*_' bash 

m*_*_*_===================================================================== 
The 'm' is there because readline has broken the line after the '00' in
the \[...\] block.

Here is the patch:

--- bash-2.05b/lib/readline/display.c   2003-12-28 21:55:30.000000000
+0000
+++ bash/lib/readline/display.c 2003-12-28 22:00:27.000000000 +0000
@@ -550,10 +550,13 @@ rl_redisplay ()
       temp = ((newlines + 1) * _rl_screenwidth) +
 #if 0
              ((newlines == 0) ? prompt_invis_chars_first_line : 0) +
+             ((newlines == 1) ? wrap_offset : 0);
 #else
-             ((newlines == 0 && local_prompt_prefix == 0) ?
prompt_invis_chars_first_line : 0) +
+             ((local_prompt_prefix == 0)
+             ? ((newlines == 0) ? prompt_invis_chars_first_line
+                     : ((newlines == 1) ? wrap_offset : 0))
+             : ((newlines == 0) ? wrap_offset : 0));
 #endif
-             ((newlines == 1) ? wrap_offset : 0);
  
       inv_lbreaks[++newlines] = temp;
       lpos -= _rl_screenwidth;


One minor extra thing (code cleanup): at 319 in the same file we need

--- bash-2.05b/lib/readline/display.c   2003-12-28 21:55:30.000000000
+0000
+++ bash/lib/readline/display.c 2003-12-28 22:00:27.000000000 +0000
@@ -316,7 +316,7 @@ rl_expand_prompt (prompt)
       t = ++p;
       local_prompt = expand_prompt (p, &prompt_visible_length,
                                       &prompt_last_invisible,
-                                      &prompt_invis_chars_first_line);
+                                      (int *)NULL);
       c = *t; *t = '\0';
       /* The portion of the prompt string up to and including the
         final newline is now null-terminated. */

this is because prompt_invis_chars_first_line is actually set a few
lines below and the value from the earlier function call is discarded.

Thanks

Ed





reply via email to

[Prev in Thread] Current Thread [Next in Thread]