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