From: Tom de Vries Date: Fri, 12 May 2023 09:43:41 +0000 (+0200) Subject: [gdb/cli] Fix wrapping for TERM=ansi X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0f6df0a04fe521ff4df9b74981a624fa2583e3a;p=binutils-gdb.git [gdb/cli] Fix wrapping for TERM=ansi I. Auto-detected width (xterm vs. ansi) Say we have a terminal with a width of 40 chars: ... $ echo $COLUMNS 40 ... With TERM=xterm, we report a width of 40 chars: ... $ TERM=xterm gdb (gdb) show width Number of characters gdb thinks are in a line is 40. ... And with TERM=ansi, a width of 39 chars: ... $ TERM=ansi gdb (gdb) show width Number of characters gdb thinks are in a line is 39. ... Gdb uses readline to auto-detect screen size, and readline decides in the TERM=ansi case that the terminal does not have reliable auto-wrap, and consequently decides to hide the last terminal column from the readline user (in other words GDB), hence we get 39 instead of 40. II. Types of wrapping Looking a bit more in detail inside gdb, it seems there are two types of wrapping: - readline wrapping (in other words, prompt edit wrapping), and - gdb output wrapping (can be observed by issuing "info sources"). This type of wrapping attempts to wrap some of the gdb output earlier than the indicated width, to not break lines in inconvenient places. III. Readline wrapping, auto-detected screen size Let's investigate readline wrapping with the auto-detected screen widths. First, 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, while readline should be capable of wrapping after 39 chars. This is caused by readline hiding the last column, twice. In more detail: - readline detects the screen width: 40, - readline hides the last column, setting the readline screen width to 39, - readline reports 39 to gdb as screen width, - gdb sets its width setting to 39, - gdb sets readline screen width to 39, - readline hides the last column, again, setting the readline screen width to 38. This is reported as PR cli/30346. IV. gdb output wrapping, auto-detected screen size Say we set the terminal width to 56. With TERM=xterm, we have: ... /home/abuild/rpmbuild/BUILD/glibc-2.31/csu/elf-init.c, /data/vries/hello.c, ... but with TERM=ansi: ... /home/abuild/rpmbuild/BUILD/glibc-2.31/csu/elf-init.c, / data/vries/hello.c, ... So what happened here? With TERM=ansi, the width setting is auto-detected to 55, and gdb assumes the terminal inserts a line break there, which it doesn't because the terminal width is 56. This is reported as PR cli/30411. V. Fix PRs Fix both mentioned PRs by taking into account the hidden column when readline reports the screen width in init_page_info, and updating chars_per_line accordingly. Note that now we report the same width for both TERM=xterm and TERM=ansi, which is much clearer. The point where readline respectively expects or ensures wrapping is still indicated by "maint info screen", for xterm: ... Number of characters readline reports are in a line is 40. ... and ansi: ... Number of characters readline reports are in a line is 39. ... VI. Testing PR cli/30346 is covered by existing regression tests gdb.base/wrap-line.exp and gdb.tui/wrap-line.exp, so remove the KFAILs there. I didn't manage to come up with a regression test for PR cli/30411. Perhaps that would be easier if we had a maintenance command that echoes its arguments while applying gdb output wrapping. Tested on x86_64-linux. PR cli/30346 PR cli/30411 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30346 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30411 --- diff --git a/gdb/testsuite/gdb.base/wrap-line.exp b/gdb/testsuite/gdb.base/wrap-line.exp index 938b5c44099..03d94720c9c 100644 --- a/gdb/testsuite/gdb.base/wrap-line.exp +++ b/gdb/testsuite/gdb.base/wrap-line.exp @@ -86,12 +86,6 @@ proc test_wrap { width_auto_detected } { gdb_assert { $gdb_width == [expr $readline_width + 1] } } - if { $width_auto_detected && $::term == "ansi" } { - if { $gdb_width == [expr $env_width - 1] || $gdb_width == $env_width } { - # Generate KFAIL or KPASS. - setup_kfail "cli/30346" "*-*-*" - } - } gdb_assert { $gdb_width == $env_width } "width" # New prompt, but avoid emitting a pass in order to avoid ending the line diff --git a/gdb/testsuite/gdb.tui/wrap-line.exp b/gdb/testsuite/gdb.tui/wrap-line.exp index b28170808b8..f1e07a7decd 100644 --- a/gdb/testsuite/gdb.tui/wrap-line.exp +++ b/gdb/testsuite/gdb.tui/wrap-line.exp @@ -92,12 +92,6 @@ proc test_wrap_cli_tui { auto_detected_width } { } } - if { $auto_detected_width } { - if { $gdb_width == [expr $::cols - 1] || $gdb_width == $::cols } { - # Generate KFAIL or KPASS. - setup_kfail "cli/30346" "*-*-*" - } - } gdb_assert { $gdb_width == $::cols } "width" # TERM=ansi, so readline hides the last column. diff --git a/gdb/utils.c b/gdb/utils.c index 0347496e431..f18228d1086 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1161,7 +1161,7 @@ init_page_info (void) readline_hidden_cols = _rl_term_autowrap ? 0 : 1; lines_per_page = rows; - chars_per_line = cols; + chars_per_line = cols + readline_hidden_cols; /* Readline should have fetched the termcap entry for us. Only try to use tgetnum function if rl_get_screen_size