]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/testsuite] Make prompt matching in Term::wait_for more strict
authorTom de Vries <tdevries@suse.de>
Thu, 14 Aug 2025 13:18:34 +0000 (15:18 +0200)
committerTom de Vries <tdevries@suse.de>
Thu, 14 Aug 2025 13:18:34 +0000 (15:18 +0200)
On x86_64-freebsd, I run into:
...
Box Dump (80 x 24) @ (0, 0):
    0 (gdb) maint info screen
    1 Number of characters gdb thinks are in a line is 90.
    2 Number of characters readline reports are in a line is 89.
    3 Number of characters curses thinks are in a line is 90.
    4 Number of characters environment thinks are in a line is 90 (COLUMNS).
    5 Number of lines gdb thinks are in a page is 40.
    6 Number of lines readline reports are in a page is 40.
    7 Number of lines curses thinks are in a page is 40.
    8 Number of lines environment thinks are in a page is 40 (LINES).
    9 Readline wrapping mode: readline (terminal is not auto wrap capable, last column
   10 .
   11 (gdb) tui disable
   12 (gdb) tui disable
   13 (gdb) maint info screen
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
FAIL: gdb.tui/resize-2.exp: again: curses width 80
...

The problem is that the prompt matching in Term::wait for is not strict enough.

It will accept a line:
...
(gdb) foo
...
as long as the cursor is pointing just after the prompt, like so:
...
(gdb) foo
      ^
...

Fix this by also checking that the line is empty.

Tested on x86_64-linux.

gdb/testsuite/gdb.tui/tuiterm-2.exp
gdb/testsuite/lib/tuiterm.exp

index 599227123bc6816929b46708065095f007bf0590..becb65ac55391028cb67107104cddcdffce25913 100644 (file)
@@ -106,6 +106,48 @@ with_override Term::accept_gdb_output test_accept_gdb_output {
                }
                gdb_assert { [Term::wait_for ""] }
            }
+
+           with_test_prefix "Term::wait_for 2" {
+               Term::_setup 4 20
+               set send_cnt 0
+               set expect_send {}
+               set action_cnt 0
+               set actions {
+                   {
+                       Term::_move_cursor 0 0
+
+                       Term::_insert "${::border}(gdb) "
+                       set pos $Term::_cur_col
+
+                       Term::_insert "foo"
+
+                       Term::_move_cursor 19 0
+                       Term::_insert "$::border"
+
+                       Term::_move_cursor $pos 0
+                   }
+                   {
+                       Term::_move_cursor 0 1
+
+                       Term::_insert "${::border}(gdb) "
+                       set pos $Term::_cur_col
+
+                       Term::_move_cursor 19 1
+                       Term::_insert "$::border"
+
+                       Term::_move_cursor $pos 1
+                   }
+               }
+
+               # Wait for a prompt.
+               gdb_assert { [Term::wait_for ""] }
+
+               # The first action sets the cursor after the prompt on the
+               # first line.  The second action sets the cursor after the
+               # prompt on the second line.   Check that wait_for returns
+               # after the second action, not the first.
+               gdb_assert { $Term::_cur_row == 1 }
+           }
        }
     }
 }
index f4a87023e2c08f12038f6c749ec7e40b4ab6cc49..7b8745ab62bb5c1bc657e7b0bf73abf56f6eba36 100644 (file)
@@ -864,16 +864,32 @@ namespace eval Term {
            } else {
                set prev [get_line $_cur_row]
            }
-           if {[regexp -- $wait_for $prev]} {
-               debug_tui_matching "$fn: match: '$prev'"
-               if {$wait_for == "$prompt_wait_for"} {
-                   break
-               }
-               set wait_for $prompt_wait_for
-               debug_tui_matching "$fn: regexp prompt: '$wait_for'"
-           } else {
+
+           if { ![regexp -- $wait_for $prev] } {
                debug_tui_matching "$fn: mismatch: '$prev'"
+               continue
+           }
+
+           if {$wait_for == "$prompt_wait_for"} {
+               # We've detected that the cursor is just after the prompt.
+               # Now check that there's nothing else on the line.
+               set prev [get_line $_cur_row]
+               if { ![regexp -- "(^|\\|)$gdb_prompt +($|\\||\\+)" $prev] } {
+                   debug_tui_matching "$fn: mismatch: '$prev'"
+                   continue
+               }
+           }
+
+           debug_tui_matching "$fn: match: '$prev'"
+
+           if {$wait_for == "$prompt_wait_for"} {
+               # Matched the prompt, we're done.
+               break
            }
+
+           # Now try to match the prompt.
+           set wait_for $prompt_wait_for
+           debug_tui_matching "$fn: regexp prompt: '$wait_for'"
        }
 
        return 1