Skip Menu |

This queue is for tickets about the Term-ReadLine-Perl CPAN distribution.

Report information
The Basics
Id: 75743
Status: open
Priority: 0/
Queue: Term-ReadLine-Perl

People
Owner: Nobody in particular
Requestors: steven.singer [...] csr.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: rl_scroll_nextline inserts line full of spaces into the output before the prompt
Date: Tue, 13 Mar 2012 18:29:12 +0000
To: bug-Term-ReadLine-Perl [...] rt.cpan.org
From: Steven Singer <Steven.Singer [...] csr.com>
I think there's a bug in the implementation of rl_scroll_nextline in Term::ReadLine::Perl. The effect of the bug is that a full line of spaces is placed into the output before the prompt is written. Since there is no newline at the end of this, copy and paste from some terminal emulators then ends up with the prompt displaced across the screen (more details about which terminals are affected later). When users copy and paste logs from programs using Term::ReadLine::Perl the results are messy. Visually, you get a blank line before the prompt. Although this does not look unattractive, this is different from Term::ReadLine::Stub, the behaviour with rl_scroll_nextline turned off and the behaviour on unaffected terminal emulators. I think the bug is in the latest version (1.0303) and has been there since the code came in (version 1.0204). I can see the problems in various versions of Perl 5.8 and in Linux versions ranging from 2.4 to 2.6. So, I don't think this is OS or Perl version related. I think the bug is caused by two spaces between \b and \r in the line that implements rl_scroll_nextline. Removing those two spaces fixes the problem. Since the two spaces start in column 80 of the line, my suspicion is that someone was indenting this section of code by two spaces in an 80 column wide editor and moved down a screen line but not a physical line. Here's my proposed diff: -------------------------------------------------------------------------------- --- readline-orig.pm 2012-03-13 15:06:15.044848000 +0000 +++ readline.pm 2012-03-13 15:06:48.996220000 +0000 @@ -1531,7 +1531,7 @@ # on XTerm one needs to increase the number by 1. - print $term_OUT ' ' x ($rl_screen_width - !$rl_last_pos_can_backspace) . "\b \r" + print $term_OUT ' ' x ($rl_screen_width - !$rl_last_pos_can_backspace) . "\b\r" if $rl_scroll_nextline; if ($dumb_term) { -------------------------------------------------------------------------------- Here's a test case and reference output. In each case, I've copied and pasted the output out of a PuTTY window or one of the other affected terminal emulators and then replaced spaces with dots in the output. I'm starting with the current Stub implementation as a reference followed by the current code and then the output with my proposed fix. In case the long lines in the following examples get mangled, here's the test Perl code formatted more normally: use Term::ReadLine; my $term = new Term::ReadLine "test"; for(;;) { print $term->readline("prompt> "), "\n"; } ================================================================================ Stub implementation ------------------- $ PERL_RL=Stub perl -e 'use Term::ReadLine; my $term = new Term::ReadLine "test"; for(;;) { print $term->readline("prompt> "), "\n"; }' Show quoted text
prompt>.foo
foo Show quoted text
prompt>.bar
bar Show quoted text
prompt>
Current Perl implementation --------------------------- $ PERL_RL=Perl perl -e 'use Term::ReadLine; my $term = new Term::ReadLine "test"; for(;;) { print $term->readline("prompt> "), "\n"; }' ................................................................................prompt>.foo foo ................................................................................prompt>.bar bar ................................................................................prompt> [In case the previous lines have got mangled, the lines containing the prompts have 80 dots before the prompt. Note that on screen, with an 80 column terminal the prompts appear in the left hand column with blank lines above them.] Perl implementation with proposed patch --------------------------------------- $ PERL_RL=Perl perl -e 'use Term::ReadLine; my $term = new Term::ReadLine "test"; for(;;) { print $term->readline("prompt> "), "\n"; }' Show quoted text
prompt>.foo
foo Show quoted text
prompt>.bar
bar Show quoted text
prompt>
================================================================================ Really, any test should also make sure that rl_scroll_newline works as intended even if just one character has been output before the prompt. Something like this might be suitable: use Term::ReadLine; my $term = new Term::ReadLine "test"; select($term->OUT); for(;;) { print "*"; print $term->readline("prompt> "), "\n"; } The problem shows in: PuTTY (version 0.62) gnome-terminal (version 2.16.0) Terminal (version 0.2.8 from xfce 4.4) screen (versions 3.09.15 (FAU) 13-Mar-03 and 4.00.03 (FAU) 23-Oct-06) konsole (Qt: 3.3.6; KDE: 3.5.4-22.el5_3 Red Hat; Konsole: 1.6.4) xterm with reverse wraparound enabled (not default?) The problem does not show in: xterm with reverse wraparound disabled (default?) I've marked default with a question mark as xterm's settings are at the mercy of lots of configuration files. It's what I get on my systems on the two versions of xterm I've tried (XFree86 4.3.99.5(179) and XTerm(215)). I think the difference in behaviour is to do with how the various terminals deal with reaching the right hand column. To simplify the example, I will assume an 80 character display. I will number the columns with column 1 being the left hand edge of the screen and column 80 being the right hand edge. If I say the cursor is in column N then the next character will be output in column N. All terminal emulators agree that after 79 spaces have been output, the cursor is in column 80. When the 80th character is output, many terminals now say the cursor is in column 81. If another character is output, the terminals go to column 1 on the next line, then output the character. If, on the other hand, with the cursor in column 81, a backspace is received the cursor goes back to column 80. With xterm (with reverse wraparound disabled) things are slightly different. With the cursor in column 80 when the next character is output, it appears that xterm places the character in column 80, leaves the cursor in column 80 and sets a flag to say the line is full. If another character is output then xterm goes to column 1 of the next line then outputs the character. If, on the other hand, a backspace is received then the cursor goes to column 79. The difference is easy to see by outputting the following sequences: 79 spaces, dot 79 spaces, backspace, dot 80 spaces, dot 80 spaces, backspace, dot All terminals agree that the first sequence puts a dot in the right hand column. All terminals agree that the second sequence puts a dot in the second column from the right. All terminals agree that the third sequence puts a dot in the left hand column of the next line. It's only the last sequence where there's a disagreement. Terminal emulators except xterm with reverse wraparound disabled put the dot in the right hand column (that is the positioning for 80 spaces plus backspace is equal to the positioning for 79 spaces). Xterm with reverse wraparound puts the dot in the second column from the right. Actually, the sample code in the comments above the rl_scroll_nextline shows the problem quite well: perl -we "print 1 x shift, qq(\b2\r3); sleep 2" 80 (I find I need to set $| to 1 to get that example to work). All the terminals except xterm with reverse wraparound disabled display: 31111111111111111111111111111111111111111111111111111111111111111111111111111112 xterm with reverse wraparound disabled displays: 31111111111111111111111111111111111111111111111111111111111111111111111111111121 I know enough about terminal emulation to know that handling the last column is tricky. So, I'm not going to say xterm's behaviour is wrong. All I'm going to say is that Term::ReadLine::Perl appears to be relying on behaviour that's peculiar to xterm with some options. -- Steven Singer Software Engineer Cambridge Silicon Radio Ltd. Tel: +44 (0)1223 692000 Fax: +44 (0)1223 692001 Churchill House, Cambridge Business Park, Cowley Road, Cambridge CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog
CC: undisclosed-recipients: ;
Subject: Re: [rt.cpan.org #75743] rl_scroll_nextline inserts line full of spaces into the output before the prompt
Date: Sat, 17 Mar 2012 15:30:59 -0700
To: Steven Singer via RT <bug-Term-ReadLine-Perl [...] rt.cpan.org>
From: Ilya Zakharevich <nospam-abuse [...] ilyaz.org>
On Tue, Mar 13, 2012 at 02:29:26PM -0400, Steven Singer via RT wrote: Show quoted text
> Tue Mar 13 14:29:26 2012: Request 75743 was acted upon. > Transaction: Ticket created by steven.singer@csr.com > Queue: Term-ReadLine-Perl > Subject: rl_scroll_nextline inserts line full of spaces into the output before the prompt > Broken in: (no value) > Severity: (no value) > Owner: Nobody > Requestors: steven.singer@csr.com > Status: new > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=75743 > > > > I think there's a bug in the implementation of rl_scroll_nextline in > Term::ReadLine::Perl. > > The effect of the bug is that a full line of spaces is placed into the > output before the prompt is written. Since there is no newline at the > end of this, copy and paste from some terminal emulators then ends up > with the prompt displaced across the screen (more details about which > terminals are affected later). When users copy and paste logs from > programs using Term::ReadLine::Perl the results are messy.
Thank you for your wonderfully detailed, clear and concise bug report. Just to make this story yet shorter, do you say that removing two spaces "fixes this" on all the terminals? And when I say "fixes this", I mean the following target: The intent of the code is: a) we want to use only spaces, tabs, \b, \t, \r, \n; b) when the cursor is at start of line, we want it to remain where it is; c) when the cursor is not at start of line, we want it to go to the beginning of the following line. I know that the code works in xterm, and in DOSISH consoles I use. I know that most terminal emulators are very buggy (when the quality stardard is set by xterm and DOSISH consoles). I'd love to have the code work even on buggy terminals, and it looks like you are in position to ameliorate this ;-). Right now I'm very limited in my time and QA abilities, but it would be great if we could resolve this together. Thanks again, Ilya
Subject: Re: [rt.cpan.org #75743] rl_scroll_nextline inserts line full of spaces into the output before the prompt
Date: Thu, 22 Mar 2012 19:08:24 +0000
To: bug-Term-ReadLine-Perl [...] rt.cpan.org
From: Steven Singer <Steven.Singer [...] csr.com>
Show quoted text
> Just to make this story yet shorter, do you say that removing two > spaces "fixes this" on all the terminals? And when I say "fixes this", I mean > the following target: > > The intent of the code is: > > a) we want to use only spaces, tabs, \b, \t, \r, \n; > b) when the cursor is at start of line, we want it to remain where it is; > c) when the cursor is not at start of line, we want it to go to the > beginning of the following line.
With the information I had when I posted my last message, I can confirm that the fix satisfies all of a through c. I hadn't tested my fix in a DOS window. What puzzles me is why the \b is in the original code. I can't work out why it's necessary or even why the original author thought that it might be necessary. That makes me nervous that there's something I've missed. So, I've tried again with and without the \b, just by using cat or type. As far as I can tell, the \b makes no difference. On an 80 column screen: 80 spaces + cr or 80 spaces + bs + cr does the right thing in xterm (with and without reverse wraparound), gnome-terminal, konsole, Terminal (part of xfce 4.4), dtterm, screen and PuTTY. 79 spaces + cr or 79 spaces + bs + cr does the right thing in a DOS (well, Windows 7) command prompt. By "the right thing" I mean the code meets condition a and, visually, b and c are satisfied. When cutting and pasting out of terminals there's some difference as to what is copied and pasted even when terminals agree visually. When the previous output leaves the cursor at the start of the line, some terminals copy and paste the spaces that were used to clear the line as being after the prompt. Other terminals ignore them. When the previous output does not leave the cursor at the start of the line, X terminals other than xterm with reverse wraparound disabled copy and paste the partial line, a bunch of spaces and then the prompt as a single line. I don't consider either of these to be significant problems and I can't see a way to fix them. Show quoted text
> I know that the code works in xterm, and in DOSISH consoles I use. I > know that most terminal emulators are very buggy (when the quality > stardard is set by xterm and DOSISH consoles). I'd love to have the > code work even on buggy terminals, and it looks like you are in > position to ameliorate this ;-).
I think calling the other terminals buggy with regard to this specific issue is probably excessive. It depends on whether you think terminals should be perfect VT100 emulations. Since you're avoiding VT100 specific escape sequences relying on behaviour peculiar to VT100 for erasing lines seems odd. If you think terminals should generally be helpful to programs then the behaviour of most terminals is understandable. It allows, for example, programs to erase the last character typed by sending "\b \b" without knowing the width of the terminal (provided the line hasn't wrapped). Using that sequence on an xterm leads to odd behaviour at the last column. If you think terminals just need to be ECMA 48 compliant rather than precise VT100 emulations then both behaviours are valid. Section 6.1.6 of the ECMA 48 spec leaves the behaviour of writing a character into the last character position up to the implementation. Termcap's description of the xn flag is equally vague. Actually, I'm assuming VT100s do what xterm does. I don't have a real VT100 to test. Show quoted text
> Right now I'm very limited in my time and QA abilities, but it would > be great if we could resolve this together.
I'm very limited in my time too but hopefully we can get this sorted. -- Steven Singer Software Engineer Cambridge Silicon Radio Ltd. Tel: +44 (0)1223 692000 Fax: +44 (0)1223 692001 Churchill House, Cambridge Business Park, Cowley Road, Cambridge CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog