"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: tog: fix display of lines ending in \r\n
To:
Christian Weisgerber <naddy@mips.inka.de>
Cc:
gameoftrees@openbsd.org
Date:
Sat, 12 Dec 2020 19:58:30 +0100

Download raw body.

Thread
On Sat, Dec 12, 2020 at 07:05:19PM +0100, Christian Weisgerber wrote:
> Stefan Sperling:
> 
> > > +			} else if (iswcntrl(wline[i])) {
> > > +				if (cols + 2 > wlimit)
> > > +					break;
> > > +				cols += 2;
> > 
> > OK. This is a nice and compact solution.
> 
> No, it is not.  I retract it.
> 
> It assumes that iswcntrl() matches the curses behavior and that
> curses will produce a two-character printable representation.  That's
> very brittle and if it is ever out of sync with what curses actually
> does, you get garbage... That didn't take long: The columns are off
> on FreeBSD.
> 
> I tried the approach with wunctrl() again, see below.  Unfortunately,
> ncurses is inconsistent.  It will actually render (wchar_t)0x9B as
> "~[", but wunctrl() says that's a printable character with width 1.
> (That diff is fine on FreeBSD, though, but it represents 0x9B with
> a space ...)
> 
> It's possible OpenBSD's ncurses is misconfigured, I don't know.
> I think the last update predates the Latin 1 to UTF-8 policy
> change.
> 
> The handling of code points 0x0080..0x009F is a sore point.
> 
> I don't know what to do.  Go through the line character by character
> and handle control char > replacement representation ourselves?

There doesn't seem to be an escaping scheme that gets away with
just one column, is there?

I'd say we can go back to using a custom single-char replacement hack.
I.e. replace the control char with '?' or something like that, and
whitelist the ones known to work (e.g. Tab). That is still better
whan what we have right now.

Once ncurses on OpenBSD has been fixed, we can go back to a better
solution that provides proper escaping for these characters.
Since you've found a good test case, perhaps nicm would be interested
in looking into this for ncurses?

By the way, I didn't really understand what your test repo did until I
ran a commit through 'got cat' and saw 'panic' blinking on my screen :)

> diff 9f6bb280654be7061fc00305743f6ace71f9a1cb /home/naddy/got
> blob - 99232045ade1a4d37286e512dd4999368a1b89b5
> file + tog/tog.c
> --- tog/tog.c
> +++ tog/tog.c
> @@ -1193,6 +1193,16 @@ format_line(wchar_t **wlinep, int *widthp, const char 
>  				if (cols + width > wlimit)
>  					break;
>  				cols += width;
> +			} else {
> +				cchar_t cch;
> +				wchar_t wch[2] = { wline[i], L'\0' };
> +
> +				if (setcchar(&cch, wch, 0, 0, NULL) == OK) {
> +					width = wcslen(wunctrl(&cch));
> +					if (cols + width > wlimit)
> +						break;
> +					cols += width;
> +				}
>  			}
>  			i++;
>  		} else {
> 
> -- 
> Christian "naddy" Weisgerber                          naddy@mips.inka.de
> 
>