Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libcurses Correct (hopefully) the handling of wide chara...



details:   https://anonhg.NetBSD.org/src/rev/6c4711489415
branches:  trunk
changeset: 359818:6c4711489415
user:      blymn <blymn%NetBSD.org@localhost>
date:      Tue Jan 25 03:05:06 2022 +0000

description:
Correct (hopefully) the handling of wide characters.

* Remove the WCOL family of macros, these were "stealing" the upper bits
  of a character attribute to store the column width of a character.  No
  warning was given about this in curses.h which meant it was easy to
  accidentally reuse the bits in use by the WCOL macros (we already did).
  Add couple of 16bit ints to the character structure iff HAVE_WCHAR is
  true to hold the display width and wide char related flags (just
  continuation at the moment)
* Convert all instances of WCOL macros to just reference the column width
  in the char structure so it is not obfuscated.
* Fix cursor positioning so placing a cursor in the middle of a wide char
  actually does just that.
* Fix plod so it understands that if the cursor is going to be positioned
  in the middle of a wide char it cannot just reprint the char to get there.
* Fix plodput so it correctly counts the number of output characters for
  wide characters.
* Fix slk routines to properly size the wctomb() buffer.

diffstat:

 lib/libcurses/add_wchstr.c     |   14 ++--
 lib/libcurses/addbytes.c       |   45 ++++++++++-----
 lib/libcurses/background.c     |    8 +-
 lib/libcurses/border.c         |   54 +++++++++---------
 lib/libcurses/clrtobot.c       |    6 +-
 lib/libcurses/clrtoeol.c       |    6 +-
 lib/libcurses/cr_put.c         |   48 +++++++++++++---
 lib/libcurses/curses_private.h |   32 ++--------
 lib/libcurses/delch.c          |   10 +-
 lib/libcurses/erase.c          |    6 +-
 lib/libcurses/in_wch.c         |    6 +-
 lib/libcurses/in_wchstr.c      |    8 +-
 lib/libcurses/ins_wch.c        |   14 ++--
 lib/libcurses/ins_wstr.c       |   12 ++--
 lib/libcurses/insch.c          |    6 +-
 lib/libcurses/insdelln.c       |    8 +-
 lib/libcurses/insstr.c         |    6 +-
 lib/libcurses/inwstr.c         |    8 +-
 lib/libcurses/newwin.c         |    8 +-
 lib/libcurses/refresh.c        |  117 +++++++++++++++++++++++++++-------------
 lib/libcurses/resize.c         |    6 +-
 lib/libcurses/slk.c            |    5 +-
 22 files changed, 250 insertions(+), 183 deletions(-)

diffs (truncated from 1416 to 300 lines):

diff -r d5ab58cdfb53 -r 6c4711489415 lib/libcurses/add_wchstr.c
--- a/lib/libcurses/add_wchstr.c        Tue Jan 25 01:56:22 2022 +0000
+++ b/lib/libcurses/add_wchstr.c        Tue Jan 25 03:05:06 2022 +0000
@@ -1,4 +1,4 @@
-/*   $NetBSD: add_wchstr.c,v 1.10 2021/09/06 07:45:48 rin Exp $ */
+/*   $NetBSD: add_wchstr.c,v 1.11 2022/01/25 03:05:06 blymn Exp $ */
 
 /*
  * Copyright (c) 2005 The NetBSD Foundation Inc.
@@ -36,7 +36,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: add_wchstr.c,v 1.10 2021/09/06 07:45:48 rin Exp $");
+__RCSID("$NetBSD: add_wchstr.c,v 1.11 2022/01/25 03:05:06 blymn Exp $");
 #endif                         /* not lint */
 
 #include <stdlib.h>
@@ -163,7 +163,7 @@
        lp = &win->alines[y]->line[x];
        lnp = win->alines[y];
 
-       cw = WCOL(*lp);
+       cw = (*lp).wcols;
        if (cw >= 0) {
                sx = x;
        } else {
@@ -174,7 +174,7 @@
                                if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
                                        return ERR;
                                tp->attr = win->battr;
-                               SET_WCOL(*tp, 1);
+                               (*tp).wcols = 1;
                                np = tp->nsp;
                        }
                } else {
@@ -211,7 +211,7 @@
                                            == ERR)
                                                return ERR;
                                        lp->attr = win->battr;
-                                       SET_WCOL(*lp, 1);
+                                       (*lp).wcols = 1;
                                        lp++, ex++;
                                }
                                ex = win->maxx - 1;
@@ -230,7 +230,7 @@
                        }
                        lp->ch = chp->vals[0];
                        lp->attr = chp->attributes & WA_ATTRIBUTES;
-                       SET_WCOL(*lp, cw);
+                       (*lp).wcols = cw;
                        if (chp->elements > 1) {
                                for (i = 1; i < chp->elements; i++) {
                                        np = (nschar_t *)
@@ -258,7 +258,7 @@
                                }
                                lp->ch = chp->vals[0];
                                lp->attr = chp->attributes & WA_ATTRIBUTES;
-                               SET_WCOL(*lp, x - ex);
+                               (*lp).wcols = x - ex;
                                lp++, ex++;
                        }
                } else {
diff -r d5ab58cdfb53 -r 6c4711489415 lib/libcurses/addbytes.c
--- a/lib/libcurses/addbytes.c  Tue Jan 25 01:56:22 2022 +0000
+++ b/lib/libcurses/addbytes.c  Tue Jan 25 03:05:06 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: addbytes.c,v 1.60 2022/01/16 10:30:45 rillig Exp $     */
+/*     $NetBSD: addbytes.c,v 1.61 2022/01/25 03:05:06 blymn Exp $      */
 
 /*
  * Copyright (c) 1987, 1993, 1994
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)addbytes.c 8.4 (Berkeley) 5/4/94";
 #else
-__RCSID("$NetBSD: addbytes.c,v 1.60 2022/01/16 10:30:45 rillig Exp $");
+__RCSID("$NetBSD: addbytes.c,v 1.61 2022/01/25 03:05:06 blymn Exp $");
 #endif
 #endif                         /* not lint */
 
@@ -203,7 +203,7 @@
 {
        static char      blank[] = " ";
        int              tabsize;
-       int              newx, i;
+       int              newx, i, wcols;
        attr_t           attributes;
 
        if (char_interp) {
@@ -275,6 +275,11 @@
        else if (win->wattr & __COLOR)
                attributes |= win->wattr & __COLOR;
 
+
+       wcols = wcwidth(c);
+       if (wcols < 0)
+               wcols = 1;
+
        /*
         * Always update the change pointers.  Otherwise,
         * we could end up not displaying 'blank' characters
@@ -294,10 +299,17 @@
            *(*lp)->firstchp, *(*lp)->lastchp,
            *(*lp)->firstchp - win->ch_off,
            *(*lp)->lastchp - win->ch_off);
-       if (win->bch != ' ' && c == ' ')
+       if (win->bch != ' ' && c == ' ') {
                (*lp)->line[*x].ch = win->bch;
-       else
+#ifdef HAVE_CHAR
+               (*lp)->line[*x].wcols = win->wcols;
+#endif
+       } else {
                (*lp)->line[*x].ch = c;
+#ifdef HAVE_CHAR
+               (*lp)->line[*x].wcols = wcols;
+#endif
+       }
 
        if (attributes & __COLOR)
                (*lp)->line[*x].attr =
@@ -391,7 +403,7 @@
                __CTRACE(__CTRACE_INPUT,
                    "_cursesi_addwchar: char '%c' is non-spacing\n",
                    wch->vals[0]);
-               cw = WCOL(*lp);
+               cw = (*lp).wcols;
                if (cw < 0) {
                        lp += cw;
                        *x += cw;
@@ -427,7 +439,7 @@
                lp = &win->alines[*y]->line[*x];
        }
        /* clear out the current character */
-       cw = WCOL(*lp);
+       cw = (*lp).wcols;
        if (cw >= 0) {
                sx = *x;
        } else {
@@ -441,7 +453,7 @@
                                return ERR;
 
                        tp->attr = win->battr;
-                       SET_WCOL(*tp, 1);
+                       tp->wcols = win->wcols;
                }
                sx = *x + cw;
                (*lnp)->flags |= __ISDIRTY;
@@ -473,7 +485,7 @@
                        if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
                                return ERR;
                        tp->attr = win->battr;
-                       SET_WCOL(*tp, 1);
+                       tp->wcols = win->wcols;
                }
                newx = win->maxx - 1 + win->ch_off;
                if (newx > *(*lnp)->lastchp)
@@ -513,11 +525,11 @@
        else
                lp->attr = attributes | win->battr;
 
-       SET_WCOL(*lp, cw);
+       lp->wcols = cw;
 
        __CTRACE(__CTRACE_INPUT,
-           "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n",
-           lp->ch, lp->attr);
+           "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x, width %d\n",
+           lp->ch, lp->attr, lp->wcols);
 
        if (wch->elements > 1) {
                for (i = 1; i < wch->elements; i++) {
@@ -547,10 +559,11 @@
                tp->ch = wch->vals[0];
                tp->attr = lp->attr & WA_ATTRIBUTES;
                /* Mark as "continuation" cell */
-               tp->attr |= __WCWIDTH;
+               tp->wflags |= WCA_CONTINUATION;
        }
 
-       if (*x == win->maxx) {
+
+       if (*x >= win->maxx) {
                __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: do line wrap\n");
                if (*y == win->scr_b) {
                        __CTRACE(__CTRACE_INPUT,
@@ -577,7 +590,7 @@
                if (*x && *x < win->maxx) {
                        ex = sx + cw;
                        tp = &win->alines[*y]->line[ex];
-                       while (ex < win->maxx && WCOL(*tp) < 0) {
+                       while (ex < win->maxx && tp->wcols < 0) {
                                __CTRACE(__CTRACE_INPUT,
                                    "_cursesi_addwchar: clear "
                                    "remaining of current char (%d,%d)nn",
@@ -586,7 +599,7 @@
                                if (_cursesi_copy_nsp(win->bnsp, tp) == ERR)
                                        return ERR;
                                tp->attr = win->battr;
-                               SET_WCOL(*tp, 1);
+                               tp->wcols = win->wcols;
                                tp++, ex++;
                        }
                        newx = ex - 1 + win->ch_off;
diff -r d5ab58cdfb53 -r 6c4711489415 lib/libcurses/background.c
--- a/lib/libcurses/background.c        Tue Jan 25 01:56:22 2022 +0000
+++ b/lib/libcurses/background.c        Tue Jan 25 03:05:06 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: background.c,v 1.27 2021/09/06 07:45:48 rin Exp $      */
+/*     $NetBSD: background.c,v 1.28 2022/01/25 03:05:06 blymn Exp $    */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: background.c,v 1.27 2021/09/06 07:45:48 rin Exp $");
+__RCSID("$NetBSD: background.c,v 1.28 2022/01/25 03:05:06 blymn Exp $");
 #endif                         /* not lint */
 
 #include <stdlib.h>
@@ -106,7 +106,7 @@
                        /* Update/merge attributes */
                        cp->attr = win->battr | (cp->attr & __ALTCHARSET);
 #ifdef HAVE_WCHAR
-                       SET_WCOL(*cp, 1);
+                       cp->wcols = 1;
 #endif
                }
        }
@@ -215,7 +215,7 @@
        if (__using_color && !( battr & __COLOR))
                battr |= __default_color;
        win->battr = battr;
-       SET_BGWCOL((*win), 1);
+       win->wcols = 1;
 }
 
 
diff -r d5ab58cdfb53 -r 6c4711489415 lib/libcurses/border.c
--- a/lib/libcurses/border.c    Tue Jan 25 01:56:22 2022 +0000
+++ b/lib/libcurses/border.c    Tue Jan 25 03:05:06 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: border.c,v 1.21 2021/10/19 06:41:03 blymn Exp $        */
+/*     $NetBSD: border.c,v 1.22 2022/01/25 03:05:06 blymn Exp $        */
 
 /*
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: border.c,v 1.21 2021/10/19 06:41:03 blymn Exp $");
+__RCSID("$NetBSD: border.c,v 1.22 2022/01/25 03:05:06 blymn Exp $");
 #endif                         /* not lint */
 
 #include <stdlib.h>
@@ -312,9 +312,9 @@
                                win->alines[i]->line[j].nsp = NULL;
                        }
                        if (j)
-                               SET_WCOL(win->alines[i]->line[j], -j);
+                               win->alines[i]->line[j].wcols = -j;
                        else {
-                               SET_WCOL(win->alines[i]->line[j], cw);
+                               win->alines[i]->line[j].wcols = cw;
                                if (left.elements > 1) {
                                        for (k = 1; k < left.elements; k++) {
                                                np = malloc(sizeof(nschar_t));
@@ -328,20 +328,20 @@
                                }
                        }
                }
-               for (j = cw; WCOL(win->alines[i]->line[j]) < 0; j++) {
+               for (j = cw; win->alines[i]->line[j].wcols < 0; j++) {
                        __CTRACE(__CTRACE_INPUT,
                            "wborder_set: clean out partial char[%d]", j);
                        win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch);
                        if (_cursesi_copy_nsp(win->bnsp,
                                              &win->alines[i]->line[j]) == ERR)
                                return ERR;
-                       SET_WCOL(win->alines[i]->line[j], 1);
+                       win->alines[i]->line[j].wcols = 1;
                }
                /* right border */
                cw = wcwidth(right.vals[0]);
                if (cw < 0)
                        cw = 1;
-               pcw = WCOL( win->alines[i]->line[endx - cw]);
+               pcw = win->alines[i]->line[endx - cw].wcols;
                for ( j = endx - cw + 1; j <= endx; j++ ) {
                        win->alines[i]->line[j].ch = right.vals[0];
                        win->alines[i]->line[j].attr = right.attributes;
@@ -355,7 +355,7 @@
                                win->alines[i]->line[j].nsp = NULL;
                        }
                        if (j == endx - cw + 1) {
-                               SET_WCOL(win->alines[i]->line[j], cw);



Home | Main Index | Thread Index | Old Index