simon-git: putty (main): Simon Tatham

Commits to Tartarus hosted VCS tartarus-commits at lists.tartarus.org
Sun Mar 5 10:33:34 GMT 2023


TL;DR:
  1b8fb1d4 terminal: remove the 'screen' parameter from lineptr().
  c890449d Expose lineptr and unlineptr outside terminal.c.
  57536cb7 Initial work on a terminal test program.
  21a31c19 Add some tests of line wrapping.
  9ba742ad Make backspace take account of LATTR_WRAPPED2.
  069f7c8b Fix behaviour of backspace in a 1-column terminal.
  ed5bf9b3 Fix printing double-width char in rightmost column without wrap.
  259de046 Run test_lineedit and test_terminal in the main build.

Repository:     https://git.tartarus.org/simon/putty.git
On the web:     https://git.tartarus.org/?p=simon/putty.git
Branch updated: main
Committer:      Simon Tatham <anakin at pobox.com>
Date:           2023-03-05 10:33:34

commit 1b8fb1d436ad5144dca32df9be846736c748c388
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=1b8fb1d436ad5144dca32df9be846736c748c388;hp=f9943e2ffdbbb2529ec5f7c1ea569fe4ee40a6a7
Author: Simon Tatham <anakin at pobox.com>
Date:   Sat Mar 4 17:04:07 2023 +0000

    terminal: remove the 'screen' parameter from lineptr().
    
    It wasn't used for anything except in an assert statement, which was
    triggered by the use of the scrlineptr() macro wrapper. Now moved that
    check into scrlineptr() itself, via a helper function that passes the
    line number of the scrlineptr() call site.
    
    (Yes, this is introducing another modalfatalbox in terminal.c, much
    like the dreaded line==NULL one that caused us so many headaches in
    past decades. But the check in question was being done _already_ by
    the assert in lineptr(), so this change shouldn't make it go off in
    any _more_ circumstances - and now, if it does, it will at least give
    us slightly more useful information about where the problem is!)

 terminal/terminal.c | 34 ++++++++++++++++++++++++++++------
 1 file changed, 28 insertions(+), 6 deletions(-)

commit c890449d76b8e5bfac188efae50e432448479a0e
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=c890449d76b8e5bfac188efae50e432448479a0e;hp=1b8fb1d436ad5144dca32df9be846736c748c388
Author: Simon Tatham <anakin at pobox.com>
Date:   Sat Mar 4 17:19:24 2023 +0000

    Expose lineptr and unlineptr outside terminal.c.
    
    This will allow test programs to look more easily at the terminal's
    data structures.

 terminal/terminal.c | 7 +++++--
 terminal/terminal.h | 3 +++
 2 files changed, 8 insertions(+), 2 deletions(-)

commit 57536cb7a3ec7604c77716f89e94799296c30a50
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=57536cb7a3ec7604c77716f89e94799296c30a50;hp=c890449d76b8e5bfac188efae50e432448479a0e
Author: Simon Tatham <anakin at pobox.com>
Date:   Sat Mar 4 17:47:01 2023 +0000

    Initial work on a terminal test program.
    
    This has all the basic necessities to become a test of the terminal's
    behaviour, in terms of how its data structures evolve as output is
    sent to it, and perhaps also (by filling in the stub TermWin more
    usefully) testing what it draws during updates and what it sends in
    response to query sequences.
    
    For the moment, all I've done is to set up the framework, and add one
    demo test of printing some ordinary text and observing that it appears
    in the data structures and the cursor has moved.
    
    I expect that writing a full test of terminal.c will be a very big
    job. But perhaps I or someone else will find time to prod it gradually
    in the background of other work. In particular, when I'm _modifying_
    any part of the terminal code, it would be good to add some tests for
    the part I'm changing, before making the change, and check they still
    work afterwards.

 terminal/terminal.h  |   7 +-
 test/test_terminal.c | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++
 unix/CMakeLists.txt  |   8 +++
 unix/platform.h      |   1 +
 windows/platform.h   |   1 +
 5 files changed, 194 insertions(+), 5 deletions(-)

commit 21a31c19b7d4584718ef47647e963465b29bcbcb
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=21a31c19b7d4584718ef47647e963465b29bcbcb;hp=57536cb7a3ec7604c77716f89e94799296c30a50
Author: Simon Tatham <anakin at pobox.com>
Date:   Sun Mar 5 09:17:29 2023 +0000

    Add some tests of line wrapping.
    
    As promised in the previous commit, I'm adding tests of the area I'm
    about to mess with.

 test/test_terminal.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 158 insertions(+)

commit 9ba742ad9f44ffddf053b77064e4b2694b2a1a37
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=9ba742ad9f44ffddf053b77064e4b2694b2a1a37;hp=21a31c19b7d4584718ef47647e963465b29bcbcb
Author: Simon Tatham <anakin at pobox.com>
Date:   Sun Mar 5 09:31:06 2023 +0000

    Make backspace take account of LATTR_WRAPPED2.
    
    Suppose an application tries to print a double-width character
    starting in the rightmost column of the screen, so that we apply our
    emergency fix of wrapping to the next line immediately and printing
    the character in the first two columns. Suppose they then backspace
    twice, taking the cursor to the RHS and then the LHS of that
    character. What should happen if they backspace a third time?
    
    Our previous behaviour was to completely ignore the unusual situation,
    and do the same thing we'd do in any other backspace from column 0:
    anti-wrap the cursor to the last column of the previous line, leaving
    it in the empty character cell that was skipped when the DW char
    couldn't be printed in it.
    
    But I think this isn't the best response, because it breaks the
    invariant that printing N columns' worth of graphic characters and
    then backspacing N times should leave the cursor on the first of those
    characters. If I print "aê°€" (for example) and then backspace three
    times, I want the cursor on the a, _even_ if weird line wrapping
    behaviour happened somewhere in that sequence.
    
    (Rationale: this helps naïve terminal applications which don't even
    know what the terminal width is, and aren't tracking their absolute x
    position. In particular, the simplistic line-based input systems that
    appear in OS kernels and our own lineedit.c will want to emit a fixed
    number of backspace-space-backspace sequences to delete characters
    previously entered on to the line by the user. They still need to
    check the wcwidth of the characters they're emitting, so that they can
    BSB twice for a DW character or 0 times for a combining one, but it
    would be *hugely* more awkward for them to ask the terminal where the
    cursor is so that they can take account of difficult line wraps!)
    
    We already have the ability to _recognise_ this situation: on a line
    that was wrapped in this unusual way, we set the LATTR_WRAPPED2 line
    attribute flag, to prevent the empty rightmost column from injecting
    an unwanted space into copy-pastes from the terminal. Now we also use
    the same flag to cause the backspace control character to do something
    interesting.
    
    This was the fix that inspired me to start writing test_terminal,
    because I knew it was touching a delicate area. However, in the course
    of writing this fix and its tests, I encountered two (!) further bugs,
    which I'll fix in followup commits!

 terminal/terminal.c  | 31 ++++++++++++++++++++++++++-----
 test/test_terminal.c |  5 +++--
 2 files changed, 29 insertions(+), 7 deletions(-)

commit 069f7c8b21df80a80445ffc986f1e243c72bc1cb
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=069f7c8b21df80a80445ffc986f1e243c72bc1cb;hp=9ba742ad9f44ffddf053b77064e4b2694b2a1a37
Author: Simon Tatham <anakin at pobox.com>
Date:   Sun Mar 5 10:01:36 2023 +0000

    Fix behaviour of backspace in a 1-column terminal.
    
    This is the first bug found as a direct result of writing that
    terminal test program - I added some tests for things I expected to
    work already, and some of them didn't, proving immediately that it was
    a good idea!
    
    If the terminal is one column wide, and you've printed a
    character (hence, set the wrapnext flag), what should backspace do?
    Surely it should behave like any other backspace with wrapnext set,
    i.e. clear the wrapnext flag, returning the cursor's _logical_
    position to the location of the most recently printed character. But
    in fact it was anti-wrapping to the previous line, because I'd got the
    cases in the wrong order in the if-else chain that forms the backspace
    handler. So the handler for 'we're in column 0, wrapping time' was
    coming before 'wrapnext is set, just clear it'.
    
    Now wrapnext is checked _first_, before checking anything at all. Any
    time we can just clear that, we should.

 terminal/terminal.c  |  7 ++++---
 test/test_terminal.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 3 deletions(-)

commit ed5bf9b3b86a45b36468a6f29d535d2f74436387
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=ed5bf9b3b86a45b36468a6f29d535d2f74436387;hp=069f7c8b21df80a80445ffc986f1e243c72bc1cb
Author: Simon Tatham <anakin at pobox.com>
Date:   Sun Mar 5 10:04:25 2023 +0000

    Fix printing double-width char in rightmost column without wrap.
    
    Another bug turned up by writing tests. The code that spots that the
    character won't fit, and wraps it to the next line setting
    LATTR_WRAPPED2, was not checking that wrap mode was _enabled_ before
    doing that. So if you printed a DW character in the rightmost column
    while the terminal was in non-auto-wrap mode, you'd get an unwanted
    wrap.
    
    Other terminals disagree on what to do here. xterm leaves the cursor
    in the same place and doesn't print any character at all.
    gnome-terminal, on the other hand, backspaces by a character so that
    it _can_ print the requested DW character, in the rightmost _two_
    columns.
    
    I think I don't much like either of those, so instead I'm using the
    same fallback we use for displaying a DW character when the whole
    terminal is only one column wide: if there is physically no room to
    print the requested character, turn it into U+FFFD REPLACEMENT
    CHARACTER.

 terminal/terminal.c  |  45 +++++++++++++---------
 test/test_terminal.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 18 deletions(-)

commit 259de04636b352573c5bb05fe731fe47aa09355e
web diff https://git.tartarus.org/?p=simon/putty.git;a=commitdiff;h=259de04636b352573c5bb05fe731fe47aa09355e;hp=ed5bf9b3b86a45b36468a6f29d535d2f74436387
Author: Simon Tatham <anakin at pobox.com>
Date:   Sun Mar 5 10:21:16 2023 +0000

    Run test_lineedit and test_terminal in the main build.
    
    These seem likely to carry on being useful, so let's make sure they
    pass before allowing any build to complete successfully. I've added
    code to both test programs to return a sensible exit status indicating
    pass/fail, and added runs of both to Buildscr.

 Buildscr             |  2 ++
 test/test_lineedit.c | 16 +++++++++++++++-
 test/test_terminal.c | 13 ++++++++++++-
 3 files changed, 29 insertions(+), 2 deletions(-)



More information about the tartarus-commits mailing list