Home | History | Annotate | Line # | Download | only in gdb.base
      1 # Copyright 2023-2024 Free Software Foundation, Inc.
      2 
      3 # This program is free software; you can redistribute it and/or modify
      4 # it under the terms of the GNU General Public License as published by
      5 # the Free Software Foundation; either version 3 of the License, or
      6 # (at your option) any later version.
      7 #
      8 # This program is distributed in the hope that it will be useful,
      9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     11 # GNU General Public License for more details.
     12 #
     13 # You should have received a copy of the GNU General Public License
     14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
     15 
     16 # Test prompt edit wrapping in CLI.
     17 
     18 # We set TERM on build, but we need to set it on host.  That only works if
     19 # build == host.
     20 require {!is_remote host}
     21 
     22 # Test both ansi (no auto-wrap) and xterm (auto-wrap).
     23 set terms {ansi xterm}
     24 
     25 # Fill line, assuming we start after the gdb prompt.
     26 proc fill_line { width } {
     27     set res ""
     28 
     29     # Take into account that the prompt also takes space.
     30     set prefix [string length "(gdb) "]
     31     set start [expr $prefix + 1]
     32 
     33     # Print chars.
     34     for { set i $start } { $i <= $width } { incr i } {
     35 	set c [expr $i % 10]
     36 	send_gdb $c
     37 	append res $c
     38     }
     39 
     40     return $res
     41 }
     42 
     43 proc get_screen_width { } {
     44     upvar gdb_width gdb_width
     45     upvar readline_width readline_width
     46     upvar env_width env_width
     47     set gdb_width 0
     48     set readline_width 0
     49     set env_width 0
     50     set re1 "Number of characters gdb thinks are in a line is ($::decimal)\[^\r\n\]*\\."
     51     set re2 \
     52 	"Number of characters readline reports are in a line is ($::decimal)\[^\r\n\]*\\."
     53     set re3 \
     54 	"Number of characters curses thinks are in a line is $::decimal\\."
     55     set re4 \
     56 	"Number of characters environment thinks are in a line is ($::decimal) \\(COLUMNS\\)."
     57     set cmd "maint info screen"
     58     set re \
     59 	[multi_line \
     60 	     ^$re1 \
     61 	     $re2 \
     62 	     "(?:$re3" \
     63 	     ")?$re4" \
     64 	     .*]
     65     gdb_test_multiple $cmd  "" {
     66 	-re -wrap $re {
     67 	    set gdb_width $expect_out(1,string)
     68 	    set readline_width $expect_out(2,string)
     69 	    set env_width $expect_out(3,string)
     70 	    pass $gdb_test_name
     71 	}
     72     }
     73 }
     74 
     75 proc test_wrap { width_auto_detected } {
     76     if { ! [readline_is_used] } {
     77 	return
     78     }
     79 
     80     get_screen_width
     81 
     82     if { $::term == "xterm" } {
     83 	gdb_assert { $gdb_width == $readline_width }
     84     } else {
     85 	gdb_assert { $gdb_width == [expr $readline_width + 1] }
     86     }
     87 
     88     gdb_assert { $gdb_width == $env_width } "width"
     89 
     90     # New prompt, but avoid emitting a pass in order to avoid ending the line
     91     # after the prompt in gdb.log.  This make it a bit easier in gdb.log to
     92     # understand where wrapping occurred.
     93     gdb_test_multiple "print 1" "" {
     94 	-re -wrap " = 1" {
     95 	}
     96     }
     97 
     98     # Fill the line to just before wrapping.
     99     set str [fill_line $readline_width]
    100 
    101     # Now print the first char we expect to wrap.
    102     send_gdb "W"
    103 
    104     # Note the difference between autowrap and no autowrap.  In the autowrap
    105     # case, readline doesn't emit a '\n', the terminal takes care of that.
    106     if { $::term == "xterm" } {
    107 	# xterm, autowrap.
    108 	set re "^${str}( |W)\rW"
    109     } else {
    110 	# ansi, no autowrap.
    111 	set re "^$str\r\n\rW"
    112     }
    113 
    114     gdb_test_multiple "" "wrap" {
    115 	-re $re {
    116 	    pass $gdb_test_name
    117 	}
    118     }
    119 
    120     # Generate a prompt.
    121     send_gdb "\003"
    122     gdb_test "" "Quit" "prompt after wrap"
    123 }
    124 
    125 foreach_with_prefix term $terms  {
    126     save_vars { env(TERM) INTERNAL_GDBFLAGS } {
    127 
    128 	setenv TERM $term
    129 
    130 	with_test_prefix width-hard-coded {
    131 	    clean_restart
    132 
    133 	    # Env_width should match whatever was set in default_gdb_init
    134 	    # using stty_init.
    135 	    with_test_prefix initial {
    136 		get_screen_width
    137 	    }
    138 	    gdb_test_no_output "set width $env_width"
    139 
    140 	    test_wrap 0
    141 	}
    142 
    143 	with_test_prefix width-auto-detected {
    144 	    # Avoid "set width 0" argument.
    145 	    set INTERNAL_GDBFLAGS \
    146 		[string map {{-iex "set width 0"} ""} $INTERNAL_GDBFLAGS]
    147 
    148 	    # Avoid "set width 0" in default_gdb_start.
    149 	    gdb_exit
    150 	    gdb_spawn
    151 
    152 	    set test "initial prompt"
    153 	    gdb_test_multiple "" $test {
    154 		-re "^$gdb_prompt $" {
    155 		    pass "$test"
    156 		}
    157 	    }
    158 
    159 	    test_wrap 1
    160 	}
    161     }
    162 }
    163