[2/2,gdb/cli] Fix wrapping for TERM=ansi
Commit Message
[ This patch requires readline_hidden_col, introduced by this patch (
https://sourceware.org/pipermail/gdb-patches/2023-April/198877.html ). ]
Say we have:
...
$ echo $COLUMNS
40
...
With xterm, we claim to wrap after 40 chars:
...
$ TERM=xterm gdb
(gdb) show width
Number of characters gdb thinks are in a line is 40.
...
And with ansi, after 39 chars:
...
$ TERM=ansi gdb
(gdb) show width
Number of characters gdb thinks are in a line is 39.
...
Let's see if that's correct. First, let's note that the prompt prefix
"(gdb) " is 6 chars long:
...
123456
(gdb)
...
so we'll tag on starting with 7.
Let's try with xterm:
...
$ TERM=xterm gdb
(gdb) 7890123456789012345678901234567890
123
...
That looks as expected, wrapping occurs after 40 chars.
Now, let's try with ansi:
...
$ TERM=ansi gdb
(gdb) 78901234567890123456789012345678
90123
...
It looks like wrapping occurred after 38 instead of 39 chars.
This is caused by:
- readline detecting the screen width: 40,
- readline substracting one from the screen width because the ansi terminal
does not support autowrap, setting the readline screen width to 39,
- readline reporting 39 to gdb as screen width,
- gdb setting readline screen width to 39,
- again readline substracting one from the screen width, setting the readline
screen width to 38.
Fix this by taking readline_hidden_cols into account in set_screen_size.
PR cli/30346
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30346
Tested on x86_64-linux.
---
gdb/testsuite/gdb.base/wrap-line.exp | 104 +++++++++++++++++++++++++++
gdb/utils.c | 2 +-
2 files changed, 105 insertions(+), 1 deletion(-)
create mode 100644 gdb/testsuite/gdb.base/wrap-line.exp
Comments
On 4/15/23 08:09, Tom de Vries via Gdb-patches wrote:
> [ This patch requires readline_hidden_col, introduced by this patch (
> https://sourceware.org/pipermail/gdb-patches/2023-April/198877.html ). ]
Hi,
I see I accidentally formatted this as a 2/2 patch. The 1/2 is
obviously the readline_hidden_cols part of the patch mentioned above.
I can submit that part separately, if anybody thinks that's a good idea,
but for now I'm hoping aforementioned patch will get accepted, and
there'll be no need.
Thanks,
- Tom
On 4/15/23 10:10, Tom de Vries via Gdb-patches wrote:
> On 4/15/23 08:09, Tom de Vries via Gdb-patches wrote:
>> [ This patch requires readline_hidden_col, introduced by this patch (
>> https://sourceware.org/pipermail/gdb-patches/2023-April/198877.html ). ]
>
> Hi,
>
> I see I accidentally formatted this as a 2/2 patch. The 1/2 is
> obviously the readline_hidden_cols part of the patch mentioned above.
>
> I can submit that part separately, if anybody thinks that's a good idea,
> but for now I'm hoping aforementioned patch will get accepted, and
> there'll be no need.
>
I've submitted a v2 here (
https://sourceware.org/pipermail/gdb-patches/2023-May/199260.html ).
Changes v2 vs v1:
- no longer fixing this in set_screen_size, but instead in
init_page_info.
- more extensive analysis in commit log, also covers PR cli/30411
which is caused by the same root cause.
- came to the conclusion that "set width" is only supposed to be
used to set the screen width, updated help text and doc to
make that more clear.
Thanks,
- Tom
new file mode 100644
@@ -0,0 +1,104 @@
+# Copyright 2023 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Check that wrapping occurs at the expected location.
+
+# We set TERM on build, but we need to set it on host. That only works if
+# build == host.
+require {!is_remote host}
+
+# Test both ansi (no auto-wrap) and xterm (auto-wrap).
+set terms {ansi xterm}
+
+foreach_with_prefix term $terms {
+ save_vars { env(TERM) INTERNAL_GDBFLAGS } {
+
+ setenv TERM $term
+
+ # Let's use the width as determined by readline to get correct
+ # wrapping in the auto-wrap case. Avoid "set width" argument.
+ set INTERNAL_GDBFLAGS \
+ [string map {{-iex "set width 0"} ""} $INTERNAL_GDBFLAGS]
+
+ # Avoid "set width" in default_gdb_start.
+ gdb_exit
+ gdb_spawn
+ }
+
+ set test "initial prompt"
+ gdb_test_multiple "" $test {
+ -re "^$gdb_prompt $" {
+ pass "$test"
+ }
+ }
+
+ if { ! [readline_is_used] } {
+ continue
+ }
+
+ set width 0
+ set show_width_re \
+ "Number of characters gdb thinks are in a line is ($decimal)\\."
+ gdb_test_multiple "show width" "" {
+ -re -wrap $show_width_re {
+ set width $expect_out(1,string)
+ pass $gdb_test_name
+ }
+ }
+
+ if { $width == 0 } {
+ continue
+ }
+
+ # New prompt, but avoid emitting a pass in order to avoid ending the line
+ # after the prompt in gdb.log. This make it a bit easier in gdb.log to
+ # understand where wrapping occurred.
+ gdb_test_multiple "print 1" "" {
+ -re -wrap " = 1" {
+ }
+ }
+
+ # Take into account that the prompt also takes space.
+ set prefix [string length "(gdb) "]
+ set start [expr $prefix + 1]
+
+ # Print chars without wrapping.
+ set i $start
+ while { 1 } {
+ send_gdb [expr $i % 10]
+ if { $i == $width } {
+ break
+ }
+ incr i
+ }
+
+ # Now print the first char we expect to wrap.
+ send_gdb "W"
+
+ # Generate a prompt.
+ send_gdb "\003"
+
+ # Note the difference between autowrap and no autowrap. In the autowrap
+ # case, readline doesn't emit a '\n', the terminal takes care of that.
+ if { $term == "xterm" } {
+ # xterm, autowrap.
+ set re "^$start\[^\r\n\]* \rWQuit"
+ } else {
+ # ansi, no autowrap.
+ set re "^$start\[^\r\n\]*\r\n\rWQuit"
+ }
+
+ gdb_test "" $re "wrap"
+}
@@ -1228,7 +1228,7 @@ static void
set_screen_size (void)
{
int rows = lines_per_page;
- int cols = chars_per_line;
+ int cols = chars_per_line + readline_hidden_cols;
/* If we get 0 or negative ROWS or COLS, treat as "infinite" size.
A negative number can be seen here with the "set width/height"