[gdb/tui] Fix tui compact-source
authorTom de Vries <tdevries@suse.de>
Wed, 10 May 2023 04:56:08 +0000 (06:56 +0200)
committerTom de Vries <tdevries@suse.de>
Wed, 10 May 2023 04:56:08 +0000 (06:56 +0200)
Consider a hello.c, with less than 10 lines:
...
$ wc -l hello.c
8 hello.c
...
and compiled with -g into an a.out.

With compact-source off:
...
$ gdb -q a.out \
    -ex "set tui border-kind ascii" \
    -ex "maint set tui-left-margin-verbose on" \
    -ex "set tui compact-source off" \
    -ex "tui enable"
...
we get:
...
+-./data/hello.c-----------------------+
|___000005_{                           |
|___000006_  printf ("hello\n");       |
|___000007_  return 0;                 |
|___000008_}                           |
|___000009_                            |
|___000010_                            |
|___000011_                            |
...
but with compact-source on:
...
+-./data/hello.c-----------------------+
|___5{                                 |
|___6  printf ("hello\n");             |
|___7  return 0;                       |
|___8}                                 |
|___9                                  |
|___1                                  |
|___1                                  |
...

There are a couple of problems with compact-source.

First of all the documentation mentions:
...
The default display uses more space for line numbers and starts the
source text at the next tab stop; the compact display uses only as
much space as is needed for the line numbers in the current file, and
only a single space to separate the line numbers from the source.
...

The bit about the default display and the next tab stop looks incorrect.  The
source doesn't start at a tab stop, instead it uses a single space to separate
the line numbers from the source.

Then the documentation mentions that there's single space in the compact
display, but evidently that's missing.

Then there's the fact that the line numbers "10" and "11" are both abbreviated
to "1" in the compact case.

The abbreviation is due to allocating space for <lines in source>, which is
8 for this example, and takes a single digit.  The line numbers though
continue past the end of the file, so fix this by allocating space for
max (<lines in source>, <last line in window>), which in this example takes 2
digits.

The missing space is due to some confusion about what the "1" here in
tui_source_window::set_contents represent:
...
      double l = log10 ((double) offsets->size ());
      m_digits = 1 + (int) l;
...

It could be the trailing space that's mentioned in tui-source.h:
...
  /* How many digits to use when formatting the line number.  This
     includes the trailing space.  */
  int m_digits;
...

Then again, it could be part of the calculation for the number of digits
needed for printing.  With this minimal example:
...
int main () {
  for (int i = 8; i <= 11; ++i) {
    double l = log10 ((double) i);
    printf ("%d %d\n", i, (int)l);
  }
  return 0;
}
...
we get:
...
$ ./a.out
8 0
9 0
10 1
11 1
...
which shows that the number of digits needed for printing i is
"1 + (int)log10 ((double) i)".

Fix this by introducing named variables needed_digits and trailing_space, each
adding 1.

With the fixes, we get for compact-source on:
...
+-./data/hello.c-----------------------+
|___05_{                               |
|___06_  printf ("hello\n");           |
|___07_  return 0;                     |
|___08_}                               |
|___09_                                |
|___10_                                |
|___11_                                |
|...

Also fix the documentation and help text to actually match effect of
compact-source.

Tested on x86_64-linux.

gdb/doc/gdb.texinfo
gdb/testsuite/gdb.tui/compact-source.exp [new file with mode: 0644]
gdb/tui/tui-source.c
gdb/tui/tui-win.c

index 8c4177c19010d146e50080183daf72b69e3dddf4..4ae84ec5a6399b9d8472e0d848aeb11224cd79d6 100644 (file)
@@ -30311,10 +30311,9 @@ assembly windows.
 @item set tui compact-source @r{[}on@r{|}off@r{]}
 @kindex set tui compact-source
 Set whether the TUI source window is displayed in ``compact'' form.
-The default display uses more space for line numbers and starts the
-source text at the next tab stop; the compact display uses only as
-much space as is needed for the line numbers in the current file, and
-only a single space to separate the line numbers from the source.
+The default display uses more space for line numbers; the compact
+display uses only as much space as is needed for the line numbers in
+the current file.
 
 @kindex set debug tui
 @item set debug tui @r{[}on|off@r{]}
diff --git a/gdb/testsuite/gdb.tui/compact-source.exp b/gdb/testsuite/gdb.tui/compact-source.exp
new file mode 100644 (file)
index 0000000..71e6b7b
--- /dev/null
@@ -0,0 +1,61 @@
+# 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 "set tui compact-source on" has the intended effect.
+
+require allow_tui_tests
+
+tuiterm_env
+
+standard_testfile
+
+# Let's generate the source file.  We want a short file, with less than 10
+# lines, and the copyright notice by itself is already more that that.
+set src_txt \
+    [join \
+        [list \
+             "int" \
+             "main (void)" \
+             "{" \
+             "  return 0;" \
+             "}"] "\n"]
+set srcfile [standard_output_file $srcfile]
+set fd [open $srcfile w]
+puts $fd $src_txt
+close $fd
+
+if {[build_executable "failed to prepare" ${testfile} ${srcfile}] == -1} {
+    return -1
+}
+
+Term::clean_restart 17 80 $binfile
+
+gdb_test_no_output "maint set tui-left-margin-verbose on"
+gdb_test_no_output "set tui compact-source on"
+
+if {![Term::enter_tui]} {
+    unsupported "TUI not supported"
+    return
+}
+
+set re_border "\\|"
+Term::check_contents "compact source format" \
+    "${re_border}___04_  return 0; *$re_border"
+
+with_test_prefix window-resize=1 {
+    Term::command "wh src -1"
+    Term::check_contents "compact source" \
+       "${re_border}___4_  return 0; *$re_border"
+}
index 3d08ea8b7cd429fba43feab79c023036183079e8..1233e945cab101b901f6acf0669166ef261d028e 100644 (file)
@@ -79,8 +79,12 @@ tui_source_window::set_contents (struct gdbarch *arch,
     {
       /* Solaris 11+gcc 5.5 has ambiguous overloads of log10, so we
         cast to double to get the right one.  */
-      double l = log10 ((double) offsets->size ());
-      m_digits = 1 + (int) l;
+      int lines_in_file = offsets->size ();
+      int last_line_nr_in_window = line_no + nlines - 1;
+      int max_line_nr = std::max (lines_in_file, last_line_nr_in_window);
+      int digits_needed = 1 + (int)log10 ((double) max_line_nr);
+      int trailing_space = 1;
+      m_digits = digits_needed + trailing_space;
     }
 
   m_max_length = -1;
index 7eac03f47a1eeb130f9de991fcc5b2f4bc85668c..6710b3e17e5bfcaf8506a087260e076b446e055c 100644 (file)
@@ -1274,8 +1274,7 @@ When enabled GDB will print a message when the terminal is resized."),
 Set whether the TUI source window is compact."), _("\
 Show whether the TUI source window is compact."), _("\
 This variable controls whether the TUI source window is shown\n\
-in a compact form.  The compact form puts the source closer to\n\
-the line numbers and uses less horizontal space."),
+in a compact form.  The compact form uses less horizontal space."),
                           tui_set_compact_source, tui_show_compact_source,
                           &tui_setlist, &tui_showlist);