public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH 5/6] [gdb/testsuite] Implement the newline glitch in tuiterm
Date: Mon, 22 May 2023 15:15:44 +0200	[thread overview]
Message-ID: <20230522131545.12291-7-tdevries@suse.de> (raw)
In-Reply-To: <20230522131545.12291-1-tdevries@suse.de>

Implement the newline glitch in tuiterm (PR testsuite/30451).  The newline
glitch corresponds to the xenl terminfo capability.  It can be enabled by
setting Term::_newline_glitch to 1.

The functionality is as follows.

After printing a char at the end of the line, rather than wrapping the cursor
goes into a special state, called the ignore state in this implementation.

The ignore state is implemented by having the cursor positioned on the same
line, but immediately right of the last column, so effectively off-screen.

In the ignore_state:
- if a normal char is issued, the cursor wraps to the next line (so the ignore
  state is no longer active) and the char is printed.
- if a control sequence is issued, the cursor is repositioned to the last column
  (so the ignore state is no longer active) and the control sequence takes effect.
- if a tab character or other formatting controls like carriage return and newline
  are issued, they are ignored.

The most elaborate description of the newline glitch I found is here [1][2].

The idea to represent the ignore state as the cursor being off the screen I
got from here [3].

Tested on x86_64-linux.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30451

[1] https://invisible-island.net/xterm/xterm.faq.html#grep_colors
[2] https://invisible-island.net/xterm/xterm.faq.html#vt100_wrapping
[3] https://stackoverflow.com/a/31360700
---
 gdb/testsuite/gdb.tui/tuiterm.exp | 26 +++++++++
 gdb/testsuite/lib/tuiterm.exp     | 94 ++++++++++++++++++++++++++++++-
 2 files changed, 118 insertions(+), 2 deletions(-)

diff --git a/gdb/testsuite/gdb.tui/tuiterm.exp b/gdb/testsuite/gdb.tui/tuiterm.exp
index 8cd15cb33bb..08b492582c3 100644
--- a/gdb/testsuite/gdb.tui/tuiterm.exp
+++ b/gdb/testsuite/gdb.tui/tuiterm.exp
@@ -682,6 +682,30 @@ proc test_insert_line { } {
     } 2 0
 }
 
+proc test_newline_glitch { } {
+    setup_terminal 8 4
+
+    # This is part of a sequence that ncurses generates when we run TUI with
+    # TERM=ansi on an xterm, in other words, when the terminal does have the
+    # newline glitch, but the terminfo entry tells ncurses that it doesn't.
+    # Consequently, we get wonky output, which gives us a good test-case for
+    # the newline glitch.
+    set Term::_newline_glitch 1
+    Term::_insert "12345678"
+    Term::_insert "12345678"
+    Term::_csi_A
+    Term::_csi_B
+    Term::_insert "(gdb) "
+    Term::dump_screen
+
+    check "newline glitch" {
+	"12345678"
+	"1234567\\("
+	"gdb\\)    "
+	"        "
+    } 5 2
+}
+
 # Run proc TEST_PROC_NAME with a "small" terminal.
 
 proc run_one_test_small { test_proc_name } {
@@ -733,3 +757,5 @@ foreach_with_prefix test {
 } {
     run_one_test_large $test
 }
+
+test_newline_glitch
diff --git a/gdb/testsuite/lib/tuiterm.exp b/gdb/testsuite/lib/tuiterm.exp
index 4c0fdc9b6df..bb0681f2034 100644
--- a/gdb/testsuite/lib/tuiterm.exp
+++ b/gdb/testsuite/lib/tuiterm.exp
@@ -33,6 +33,8 @@ namespace eval Term {
 
     variable _resize_count
 
+    variable _newline_glitch
+
     proc _log { what } {
 	verbose "+++ $what"
     }
@@ -50,6 +52,19 @@ namespace eval Term {
 	_log "$what, cursor: ($orig_cur_row, $orig_cur_col) -> ($_cur_row, $_cur_col)"
     }
 
+    proc in_ignore_state {} {
+	variable _cur_col
+	variable _cols
+	return [expr $_cur_col == $_cols]
+    }
+
+    proc cancel_ignore_state {} {
+	variable _cur_col
+	if { [in_ignore_state] } {
+	    incr _cur_col -1
+	}
+    }
+
     # If ARG is empty, return DEF: otherwise ARG.  This is useful for
     # defaulting arguments in CSIs.
     proc _default {arg def} {
@@ -81,10 +96,19 @@ namespace eval Term {
 
     # Beep.
     proc _ctl_0x07 {} {
+	if { [in_ignore_state] } {
+	    _log "Beep: ignored"
+	    return
+	}
     }
 
     # Backspace.
     proc _ctl_0x08 {} {
+	if { [in_ignore_state] } {
+	    _log "Backspace: ignored"
+	    return
+	}
+
 	_log_cur "Backspace" {
 	    variable _cur_col
 
@@ -96,6 +120,11 @@ namespace eval Term {
 
     # Linefeed.
     proc _ctl_0x0a {} {
+	if { [in_ignore_state] } {
+	    _log "Line feed: ignored"
+	    return
+	}
+
 	_log_cur "Line feed" {
 	    variable _cur_row
 	    variable _rows
@@ -123,6 +152,11 @@ namespace eval Term {
 
     # Carriage return.
     proc _ctl_0x0d {} {
+	if { [in_ignore_state] } {
+	    _log "Carriage return: ignored"
+	    return
+	}
+
 	_log_cur "Carriage return" {
 	    variable _cur_col
 
@@ -134,6 +168,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/ICH.html
     proc _csi_@ {args} {
+	cancel_ignore_state
+
 	set n [_default [lindex $args 0] 1]
 
 	_log_cur "Insert Character ($n)" {
@@ -158,6 +194,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CUU.html
     proc _csi_A {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Up ($arg)" {
@@ -171,6 +209,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CUD.html
     proc _csi_B {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Down ($arg)" {
@@ -185,6 +225,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CUF.html
     proc _csi_C {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Forward ($arg)" {
@@ -199,6 +241,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CUB.html
     proc _csi_D {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Backward ($arg)" {
@@ -212,6 +256,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CNL.html
     proc _csi_E {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Next Line ($arg)" {
@@ -228,6 +274,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CPL.html
     proc _csi_F {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Previous Line ($arg)" {
@@ -244,6 +292,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CHA.html
     proc _csi_G {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Horizontal Absolute ($arg)" {
@@ -258,6 +308,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CUP.html
     proc _csi_H {args} {
+	cancel_ignore_state
+
 	set row [_default [lindex $args 0] 1]
 	set col [_default [lindex $args 1] 1]
 
@@ -274,6 +326,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CHT.html
     proc _csi_I {args} {
+	cancel_ignore_state
+
 	set n [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Horizontal Forward Tabulation ($n)" {
@@ -291,6 +345,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/ED.html
     proc _csi_J {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 0]
 
 	_log_cur "Erase in Display ($arg)" {
@@ -318,6 +374,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/EL.html
     proc _csi_K {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 0]
 
 	_log_cur "Erase in Line ($arg)" {
@@ -342,6 +400,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/IL.html
     proc _csi_L {args} {
+	cancel_ignore_state
+
 	set arg [_default [lindex $args 0] 1]
 
 	_log_cur "Insert Line ($arg)" {
@@ -369,6 +429,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/DL.html
     proc _csi_M {args} {
+	cancel_ignore_state
+
 	set count [_default [lindex $args 0] 1]
 
 	_log_cur "Delete line ($count)" {
@@ -394,6 +456,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/DCH.html
     proc _csi_P {args} {
+	cancel_ignore_state
+
 	set count [_default [lindex $args 0] 1]
 
 	_log_cur "Delete character ($count)" {
@@ -421,6 +485,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/SU.html
     proc _csi_S {args} {
+	cancel_ignore_state
+
 	set count [_default [lindex $args 0] 1]
 
 	_log_cur "Pan Down ($count)" {
@@ -455,6 +521,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/SD.html
     proc _csi_T {args} {
+	cancel_ignore_state
+
 	set count [_default [lindex $args 0] 1]
 
 	_log_cur "Pan Up ($count)" {
@@ -489,6 +557,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/ECH.html
     proc _csi_X {args} {
+	cancel_ignore_state
+
 	set n [_default [lindex $args 0] 1]
 
 	_log_cur "Erase chars ($n)" {
@@ -511,6 +581,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/CBT.html
     proc _csi_Z {args} {
+	cancel_ignore_state
+
 	set n [_default [lindex $args 0] 1]
 
 	_log_cur "Cursor Backward Tabulation ($n)" {
@@ -524,6 +596,8 @@ namespace eval Term {
     #
     # https://www.xfree86.org/current/ctlseqs.html (See `(REP)`)
     proc _csi_b {args} {
+	cancel_ignore_state
+
 	set n [_default [lindex $args 0] 1]
 
 	_log_cur "Repeat ($n)" {
@@ -537,6 +611,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/VPA.html
     proc _csi_d {args} {
+	cancel_ignore_state
+
 	set row [_default [lindex $args 0] 1]
 
 	_log_cur "Vertical Line Position Absolute ($row)" {
@@ -563,6 +639,8 @@ namespace eval Term {
     #
     # https://vt100.net/docs/vt510-rm/SGR.html
     proc _csi_m {args} {
+	cancel_ignore_state
+
 	_log_cur "Select Graphic Rendition ([join $args {, }])" {
 	    variable _attrs
 
@@ -631,13 +709,23 @@ namespace eval Term {
 	    variable _cols
 	    variable _attrs
 	    variable _chars
+	    variable _newline_glitch
 	    set lattr [array get _attrs]
 	    foreach char [split $str {}] {
 		_log_cur "  Inserted char '$char'" {
+		    if { $_newline_glitch } {
+			if { $_cur_col == $_cols} {
+			    _wrap_cursor
+			}
+		    }
+
 		    set _chars($_cur_col,$_cur_row) [list $char $lattr]
 		    incr _cur_col
-		    if {$_cur_col >= $_cols} {
-			_wrap_cursor
+
+		    if { !$_newline_glitch } {
+			if {$_cur_col == $_cols} {
+			    _wrap_cursor
+			}
 		    }
 		}
 	    }
@@ -675,12 +763,14 @@ namespace eval Term {
 	variable _cur_row
 	variable _attrs
 	variable _resize_count
+	variable _newline_glitch
 
 	set _rows $rows
 	set _cols $cols
 	set _cur_col 0
 	set _cur_row 0
 	set _resize_count 0
+	set _newline_glitch 0
 	_reset_attrs _attrs
 
 	_clear_lines 0 $_rows
-- 
2.35.3


  parent reply	other threads:[~2023-05-22 13:15 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-22 13:15 [PATCH 0/6] [gdb/tui] Introduce ansi-for-tui Tom de Vries
2023-05-22 13:15 ` [PATCH 1/6] [gdb/testsuite] Use TERM=dummy in gdb.tui/tuiterm.exp Tom de Vries
2023-05-22 13:15 ` [PATCH] [gdb/tui] Add set style tui-status-window Tom de Vries
2023-05-22 13:47   ` Eli Zaretskii
2023-05-22 14:22     ` Tom de Vries
2023-05-22 15:50       ` Eli Zaretskii
2023-05-22 13:15 ` [PATCH 2/6] [gdb/testsuite] Factor out Term::_wrap_cursor Tom de Vries
2023-05-22 13:15 ` [PATCH 3/6] [gdb/contrib] Add ansi-for-tui.sh Tom de Vries
2023-05-22 13:15 ` [PATCH 4/6] [gdb/testsuite] Make ansi-for-tui available in with_tuiterm Tom de Vries
2023-05-22 13:15 ` Tom de Vries [this message]
2023-05-22 13:15 ` [PATCH 6/6] [gdb/testsuite] Use ansi-for-tui in tuiterm Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230522131545.12291-7-tdevries@suse.de \
    --to=tdevries@suse.de \
    --cc=gdb-patches@sourceware.org \
    --cc=tom@tromey.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).