tech-userlevel archive

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

libcurses widechar fixes for review



Hi -

here is a patch which fixes various bugs in libcurses which mostly
show up if one tries to use the box/border linedrawing functions
with a UTF-8 locale.
I'll give a short comment on each issue fixed, in the order of
occurence in the patch. Would be nice if someone had a look
at it, in particilar where it touches i18n.
The fixes:
1. Not a real bug: the check of the "aofac" pointer against
  '\0' in __init_acs and __init_wacs doesn't make sense.
2. nl_langinfo(CODESET) does only work as expected if someone
   called setlocale(LC_CTYPE, "") before (or LC_ALL). Since it
   is not documented that the caller has to do it, we need to
   do it. To avoid interference with user code, do it only
   if the locale it still at the "C" default.
3. The UTF-8 check in __init_wacs was reversed.
4. POSIX etc say that the WACS_* symbols are of type cchar_t*,
   in particular they should be usable as arguments to
   border_set().
5. wcwidth() returns -1 if it figures that the character is not
   printable (it can change its opinion at runtime if the
   locale settings change -- sysinst does this). The return value
   is used in loop count calculations etc. I've just blindly added
   a safeguard which assumes a width of 1. Perhaps not optimal,
   but it prevents loop counts, array indices etc from going
   out of bounds.
6. wborder() doesn't work with a UTF-8 terminal because it
   uses the ACS_* definitions. My patch tries to fix this by
   using wborder_set() for the work in the HAVE_WCHAR case.
   The attribute translation from chtype to cchar_t is incomplete,
   perhaps the use of setcchar() should be reconsidered here.
7. There was also a bug that wborder_set() doesn't get the
   ALTCHARSET flag of the WACS_VLINE etc characters -- it
   used just the "vals" part, not the attribute. This is fixed
   together with issue (4) above -- memcpy() copies it all.

best regards
Matthias


------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich
Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDir'in Baerbel Brumme-Bothe
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Dr. Ulrich Krafft (stellv. Vorsitzender), Prof. Dr.-Ing. Harald Bolt,
Prof. Dr. Sebastian M. Schmidt
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
#
# old_revision [ee02a39d876d30a33abb84078c81c72f8bc5f3fd]
#
# patch "lib/libcurses/acs.c"
#  from [44f73fc19634afbf1c5bc4f27710bc3a1529e30f]
#    to [a39a51239cc1131502db037fc221a7dc3dac8466]
# 
# patch "lib/libcurses/add_wchstr.c"
#  from [32be2860ed9cfad6fa4e88a44c82b3c6c95e2a34]
#    to [7bb402c3b0e9a37cb4bf1b8d1d6b6146d6d8b3fd]
# 
# patch "lib/libcurses/addbytes.c"
#  from [b3ed0d5ee1eba8e885a59e5a6c03dcb153961497]
#    to [ac3cb22c1effe10848360511362c87297249f469]
# 
# patch "lib/libcurses/border.c"
#  from [682ed99339aa04be2c7de749a2d692ea1abc33ad]
#    to [36553e8407964ef6065d1264a178b1d9b58443d4]
# 
# patch "lib/libcurses/curses.h"
#  from [dc6725ec927df337446b97662753bfc101a58eef]
#    to [0a3748d4a66581a1c07709ec3ee5dbbf0f13071a]
# 
# patch "lib/libcurses/ins_wch.c"
#  from [f4b07b220495adb302495bab4e29b37dbdf5db22]
#    to [895654fbc4a088cb32a1f72a790c98016c7c7f64]
# 
# patch "lib/libcurses/ins_wstr.c"
#  from [d8e1c97327d0fd9f0463872aca91f1a4ec750ccc]
#    to [193072eb1e6e1c7f4cbc7e5d2fcc12ae252d9289]
# 
# patch "lib/libcurses/line.c"
#  from [15b60f8d9aaae4e76a14498d1f7550473c3d18c4]
#    to [e73017ae997ae8c5e85863c4eb243d475dd520bf]
#
============================================================
--- lib/libcurses/acs.c 44f73fc19634afbf1c5bc4f27710bc3a1529e30f
+++ lib/libcurses/acs.c a39a51239cc1131502db037fc221a7dc3dac8466
@@ -40,6 +40,7 @@ chtype _acs_char[NUM_ACS];
 chtype _acs_char[NUM_ACS];
 #ifdef HAVE_WCHAR
 #include <assert.h>
+#include <locale.h>
 #include <langinfo.h>
 #include <strings.h>
 
@@ -105,10 +106,8 @@ __init_acs(SCREEN *screen)
        while (*aofac != '\0') {
                if ((acs = *aofac) == '\0')
                        return;
-               if (++aofac == '\0')
+               if ((term = *++aofac) == '\0')
                        return;
-               if ((term = *aofac) == '\0')
-                       return;
                /* Only add characters 1 to 127 */
                if (acs < NUM_ACS)
                        _acs_char[acs] = term | __ALTCHARSET;
@@ -158,72 +157,74 @@ __init_wacs(SCREEN *screen)
        }
 
        /* Add the SUSv2 defaults (those that are not '+') */
+       if (!strcmp(setlocale(LC_CTYPE, NULL), "C"))
+               setlocale(LC_CTYPE, "");
        lstr = nl_langinfo(CODESET);
        _DIAGASSERT(lstr);
-       if (!strcasecmp(lstr, "UTF-8")) {
+       if (strcasecmp(lstr, "UTF-8")) {
 #ifdef DEBUG
                __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" );
 #endif /* DEBUG */
-               WACS_RARROW  = ( wchar_t )btowc( '>' );
-               WACS_LARROW  = ( wchar_t )btowc( '<' );
-               WACS_UARROW  = ( wchar_t )btowc( '^' );
-               WACS_DARROW  = ( wchar_t )btowc( 'v' );
-               WACS_BLOCK   = ( wchar_t )btowc( '#' );
-               WACS_CKBOARD = ( wchar_t )btowc( ':' );
-               WACS_DEGREE  = ( wchar_t )btowc( 39 );  /* ' */
-               WACS_PLMINUS = ( wchar_t )btowc( '#' );
-               WACS_BOARD   = ( wchar_t )btowc( '#' );
-               WACS_LANTERN = ( wchar_t )btowc( '#' );
-               WACS_HLINE   = ( wchar_t )btowc( '-' );
-               WACS_S1   = ( wchar_t )btowc( '-' );
-               WACS_S9   = ( wchar_t )btowc( '_' );
-               WACS_VLINE   = ( wchar_t )btowc( '|' );
-               WACS_BULLET  = ( wchar_t )btowc( 'o' );
-               WACS_S3 = ( wchar_t )btowc( 'p' );
-               WACS_S7 = ( wchar_t )btowc( 'r' );
-               WACS_LEQUAL = ( wchar_t )btowc( 'y' );
-               WACS_GEQUAL = ( wchar_t )btowc( 'z' );
-               WACS_PI = ( wchar_t )btowc( '{' );
-               WACS_NEQUAL = ( wchar_t )btowc( '|' );
-               WACS_STERLING = ( wchar_t )btowc( '}' );
+               WACS_RARROW->vals[0]  = ( wchar_t )btowc( '>' );
+               WACS_LARROW->vals[0]  = ( wchar_t )btowc( '<' );
+               WACS_UARROW->vals[0]  = ( wchar_t )btowc( '^' );
+               WACS_DARROW->vals[0]  = ( wchar_t )btowc( 'v' );
+               WACS_BLOCK->vals[0]   = ( wchar_t )btowc( '#' );
+               WACS_CKBOARD->vals[0] = ( wchar_t )btowc( ':' );
+               WACS_DEGREE->vals[0]  = ( wchar_t )btowc( 39 ); /* ' */
+               WACS_PLMINUS->vals[0] = ( wchar_t )btowc( '#' );
+               WACS_BOARD->vals[0]   = ( wchar_t )btowc( '#' );
+               WACS_LANTERN->vals[0] = ( wchar_t )btowc( '#' );
+               WACS_HLINE->vals[0]   = ( wchar_t )btowc( '-' );
+               WACS_S1->vals[0]      = ( wchar_t )btowc( '-' );
+               WACS_S9->vals[0]      = ( wchar_t )btowc( '_' );
+               WACS_VLINE->vals[0]   = ( wchar_t )btowc( '|' );
+               WACS_BULLET->vals[0]  = ( wchar_t )btowc( 'o' );
+               WACS_S3->vals[0]      = ( wchar_t )btowc( 'p' );
+               WACS_S7->vals[0]      = ( wchar_t )btowc( 'r' );
+               WACS_LEQUAL->vals[0]  = ( wchar_t )btowc( 'y' );
+               WACS_GEQUAL->vals[0]  = ( wchar_t )btowc( 'z' );
+               WACS_PI->vals[0]      = ( wchar_t )btowc( '{' );
+               WACS_NEQUAL->vals[0]  = ( wchar_t )btowc( '|' );
+               WACS_STERLING->vals[0]= ( wchar_t )btowc( '}' );
        } else {
                /* Unicode defaults */
 #ifdef DEBUG
                __CTRACE(__CTRACE_INIT,
                    "__init_wacs: setting Unicode defaults\n" );
 #endif /* DEBUG */
-               WACS_RARROW      = 0x2192;
-               WACS_LARROW      = 0x2190;
-               WACS_UARROW      = 0x2192;
-               WACS_DARROW      = 0x2193;
-               WACS_BLOCK        = 0x25ae;
-               WACS_DIAMOND    = 0x25c6;
-               WACS_CKBOARD    = 0x2592;
-               WACS_DEGREE      = 0x00b0;
-               WACS_PLMINUS    = 0x00b1;
-               WACS_BOARD        = 0x2592;
-               WACS_LANTERN    = 0x2603;
-               WACS_LRCORNER   = 0x2518;
-               WACS_URCORNER   = 0x2510;
-               WACS_ULCORNER   = 0x250c;
-               WACS_LLCORNER   = 0x2514;
-               WACS_PLUS          = 0x253c;
-               WACS_HLINE        = 0x2500;
-               WACS_S1          = 0x23ba;
-               WACS_S9          = 0x23bd;
-               WACS_LTEE          = 0x251c;
-               WACS_RTEE          = 0x2524;
-               WACS_BTEE          = 0x2534;
-               WACS_TTEE          = 0x252c;
-               WACS_VLINE        = 0x2502;
-               WACS_BULLET      = 0x00b7;
-               WACS_S3          = 0x23bb;
-               WACS_S7          = 0x23bc;
-               WACS_LEQUAL      = 0x2264;
-               WACS_GEQUAL      = 0x2265;
-               WACS_PI          = 0x03C0;
-               WACS_NEQUAL      = 0x2260;
-               WACS_STERLING    = 0x00A3;
+               WACS_RARROW->vals[0]  = 0x2192;
+               WACS_LARROW->vals[0]  = 0x2190;
+               WACS_UARROW->vals[0]  = 0x2192;
+               WACS_DARROW->vals[0]  = 0x2193;
+               WACS_BLOCK->vals[0]   = 0x25ae;
+               WACS_DIAMOND->vals[0] = 0x25c6;
+               WACS_CKBOARD->vals[0] = 0x2592;
+               WACS_DEGREE->vals[0]  = 0x00b0;
+               WACS_PLMINUS->vals[0] = 0x00b1;
+               WACS_BOARD->vals[0]   = 0x2592;
+               WACS_LANTERN->vals[0] = 0x2603;
+               WACS_LRCORNER->vals[0]= 0x2518;
+               WACS_URCORNER->vals[0]= 0x2510;
+               WACS_ULCORNER->vals[0]= 0x250c;
+               WACS_LLCORNER->vals[0]= 0x2514;
+               WACS_PLUS->vals[0]    = 0x253c;
+               WACS_HLINE->vals[0]   = 0x2500;
+               WACS_S1->vals[0]      = 0x23ba;
+               WACS_S9->vals[0]      = 0x23bd;
+               WACS_LTEE->vals[0]    = 0x251c;
+               WACS_RTEE->vals[0]    = 0x2524;
+               WACS_BTEE->vals[0]    = 0x2534;
+               WACS_TTEE->vals[0]    = 0x252c;
+               WACS_VLINE->vals[0]   = 0x2502;
+               WACS_BULLET->vals[0]  = 0x00b7;
+               WACS_S3->vals[0]      = 0x23bb;
+               WACS_S7->vals[0]      = 0x23bc;
+               WACS_LEQUAL->vals[0]  = 0x2264;
+               WACS_GEQUAL->vals[0]  = 0x2265;
+               WACS_PI->vals[0]      = 0x03C0;
+               WACS_NEQUAL->vals[0]  = 0x2260;
+               WACS_STERLING->vals[0]= 0x00A3;
        }
 
        if (t_acs_chars(screen->term) == NULL) {
@@ -239,10 +240,8 @@ __init_wacs(SCREEN *screen)
        while (*aofac != '\0') {
                if ((acs = *aofac) == '\0')
                        return;
-               if (++aofac == '\0')
+               if ((term = *++aofac) == '\0')
                        return;
-               if ((term = *aofac) == '\0')
-                       return;
                /* Only add characters 1 to 127 */
                if (acs < NUM_ACS) {
                        _wacs_char[acs].vals[ 0 ] = term;
============================================================
--- lib/libcurses/add_wchstr.c  32be2860ed9cfad6fa4e88a44c82b3c6c95e2a34
+++ lib/libcurses/add_wchstr.c  7bb402c3b0e9a37cb4bf1b8d1d6b6146d6d8b3fd
@@ -233,6 +233,8 @@ wadd_wchnstr(WINDOW *win, const cchar_t 
                __CTRACE(__CTRACE_INPUT, "wadd_wchnstr: adding %x", wc);
 #endif /* DEBUG */
                cw = wcwidth(wc);
+               if (cw < 0)
+                       cw = 1;
                if (cw) {
                        /* spacing character */
 #ifdef DEBUG
============================================================
--- lib/libcurses/addbytes.c    b3ed0d5ee1eba8e885a59e5a6c03dcb153961497
+++ lib/libcurses/addbytes.c    ac3cb22c1effe10848360511362c87297249f469
@@ -438,6 +438,8 @@ _cursesi_addwchar(WINDOW *win, __LINE **
 
        /* check for enough space before the end of line */
        cw = wcwidth(wch->vals[0]);
+       if (cw < 0)
+               cw = 1;
        if (cw > win->maxx - *x) {
 #ifdef DEBUG
                __CTRACE(__CTRACE_INPUT,
============================================================
--- lib/libcurses/border.c      682ed99339aa04be2c7de749a2d692ea1abc33ad
+++ lib/libcurses/border.c      36553e8407964ef6065d1264a178b1d9b58443d4
@@ -66,6 +66,7 @@ wborder(WINDOW *win, chtype left, chtype
 wborder(WINDOW *win, chtype left, chtype right, chtype top, chtype bottom,
        chtype topleft, chtype topright, chtype botleft, chtype botright)
 {
+#ifndef HAVE_WCHAR
        int      endy, endx, i;
        __LDATA *fp, *lp;
 
@@ -134,20 +135,12 @@ wborder(WINDOW *win, chtype left, chtype
                win->alines[i]->line[0].attr = (attr_t) left & __ATTRIBUTES;
                win->alines[i]->line[endx].ch = (wchar_t) right & __CHARTEXT;
                win->alines[i]->line[endx].attr = (attr_t) right & __ATTRIBUTES;
-#ifdef HAVE_WCHAR
-               SET_WCOL(win->alines[i]->line[0], 1);
-               SET_WCOL(win->alines[i]->line[endx], 1);
-#endif
        }
        for (i = 1; i < endx; i++) {
                fp[i].ch = (wchar_t) top & __CHARTEXT;
                fp[i].attr = (attr_t) top & __ATTRIBUTES;
                lp[i].ch = (wchar_t) bottom & __CHARTEXT;
                lp[i].attr = (attr_t) bottom & __ATTRIBUTES;
-#ifdef HAVE_WCHAR
-               SET_WCOL(fp[i], 1);
-               SET_WCOL(lp[i], 1);
-#endif
        }
 
        /* Corners */
@@ -161,15 +154,33 @@ wborder(WINDOW *win, chtype left, chtype
                lp[0].attr = (attr_t) botleft & __ATTRIBUTES;
                lp[endx].ch = (wchar_t) botright & __CHARTEXT;
                lp[endx].attr = (attr_t) botright & __ATTRIBUTES;
-#ifdef HAVE_WCHAR
-               SET_WCOL(fp[0], 1);
-               SET_WCOL(fp[endx], 1);
-               SET_WCOL(lp[0], 1);
-               SET_WCOL(lp[endx], 1);
-#endif
        }
        __touchwin(win);
        return (OK);
+#else /* HAVE_WCHAR */
+       cchar_t ls, rs, ts, bs, tl, tr, bl, br;
+       cchar_t *lsp, *rsp, *tsp, *bsp, *tlp, *trp, *blp, *brp;
+       wchar_t tmp[2];
+
+#define S(in, out) \
+       if (in & __CHARTEXT) { \
+               tmp[0] = in; \
+               tmp[1] = 0; \
+               setcchar(&out, tmp, win->wattr, 0, NULL); \
+               out##p = &out; \
+       } else \
+               out##p = NULL
+       S(left, ls);
+       S(right, rs);
+       S(top, ts);
+       S(bottom, bs);
+       S(topleft, tl);
+       S(topright, tr);
+       S(botleft, bl);
+       S(botright, br);
+#undef S
+       return wborder_set(win, lsp, rsp, tsp, bsp, tlp, trp, blp, brp);
+#endif /* HAVE_WCHAR */
 }
 
 int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts,
@@ -197,36 +208,38 @@ int wborder_set(WINDOW *win, const cchar
 
        if ( ls && wcwidth( ls->vals[ 0 ]))
                memcpy( &left, ls, sizeof( cchar_t ));
-       else
-               setcchar( &left, &WACS_VLINE, win->wattr, 0, NULL );
+       else {
+               memcpy( &left, WACS_VLINE, sizeof( cchar_t ));
+               /* XXX win->wattr? */
+       }
        if ( rs && wcwidth( rs->vals[ 0 ]))
                memcpy( &right, rs, sizeof( cchar_t ));
        else
-               setcchar( &right, &WACS_VLINE, win->wattr, 0, NULL );
+               memcpy( &right, WACS_VLINE, sizeof( cchar_t ));
        if ( ts && wcwidth( ts->vals[ 0 ]))
                memcpy( &top, ts, sizeof( cchar_t ));
        else
-               setcchar( &top, &WACS_HLINE, win->wattr, 0, NULL );
+               memcpy( &top, WACS_HLINE, sizeof( cchar_t ));
        if ( bs && wcwidth( bs->vals[ 0 ]))
                memcpy( &bottom, bs, sizeof( cchar_t ));
        else
-               setcchar( &bottom, &WACS_HLINE, win->wattr, 0, NULL );
+               memcpy( &bottom, WACS_HLINE, sizeof( cchar_t ));
        if ( tl && wcwidth( tl->vals[ 0 ]))
                memcpy( &topleft, tl, sizeof( cchar_t ));
        else
-               setcchar( &topleft, &WACS_ULCORNER, win->wattr, 0, NULL );
+               memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t ));
        if ( tr && wcwidth( tr->vals[ 0 ]))
                memcpy( &topright, tr, sizeof( cchar_t ));
        else
-               setcchar( &topright, &WACS_URCORNER, win->wattr, 0, NULL );
+               memcpy( &topright, WACS_URCORNER, sizeof( cchar_t ));
        if ( bl && wcwidth( bl->vals[ 0 ]))
                memcpy( &botleft, bl, sizeof( cchar_t ));
        else
-               setcchar( &botleft, &WACS_LLCORNER, win->wattr, 0, NULL );
+               memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t ));
        if ( br && wcwidth( br->vals[ 0 ]))
                memcpy( &botright, br, sizeof( cchar_t ));
        else
-               setcchar( &botright, &WACS_LRCORNER, win->wattr, 0, NULL );
+               memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t ));
 
 #ifdef DEBUG
        __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n",
@@ -272,6 +285,8 @@ int wborder_set(WINDOW *win, const cchar
        for (i = 1; i < endy; i++) {
                /* left border */
                cw = wcwidth( left.vals[ 0 ]);
+               if (cw < 0)
+                       cw = 1;
                for ( j = 0; j < cw; j++ ) {
                        win->alines[i]->line[j].ch = left.vals[ 0 ];
                        win->alines[i]->line[j].attr = left.attributes;
@@ -314,6 +329,8 @@ int wborder_set(WINDOW *win, const cchar
                }
                /* right border */
                cw = wcwidth( right.vals[ 0 ]);
+               if (cw < 0)
+                       cw = 1;
                pcw = WCOL( win->alines[i]->line[endx - cw]);
                for ( j = endx - cw + 1; j <= endx; j++ ) {
                        win->alines[i]->line[j].ch = right.vals[ 0 ];
@@ -363,11 +380,21 @@ int wborder_set(WINDOW *win, const cchar
                }
        }
        tlcw = wcwidth( topleft.vals[ 0 ]);
+       if (tlcw < 0)
+               tlcw = 1;
        blcw = wcwidth( botleft.vals[ 0 ]);
+       if (blcw < 0)
+               blcw = 1;
        trcw = wcwidth( topright.vals[ 0 ]);
+       if (trcw < 0)
+               trcw = 1;
        brcw = wcwidth( botright.vals[ 0 ]);
+       if (brcw < 0)
+               brcw = 1;
        /* upper border */
        cw = wcwidth( top.vals[ 0 ]);
+       if (cw < 0)
+               cw = 1;
        for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) {
                for ( j = 0; j < cw; j++ ) {
                        win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ];
============================================================
--- lib/libcurses/curses.h      dc6725ec927df337446b97662753bfc101a58eef
+++ lib/libcurses/curses.h      0a3748d4a66581a1c07709ec3ee5dbbf0f13071a
@@ -325,38 +325,38 @@ extern cchar_t _wacs_char[NUM_ACS];
 #ifdef HAVE_WCHAR
 extern cchar_t _wacs_char[NUM_ACS];
 
-#define        WACS_RARROW     _wacs_char[(unsigned char)'+'].vals[0]
-#define        WACS_LARROW     _wacs_char[(unsigned char)','].vals[0]
-#define        WACS_UARROW     _wacs_char[(unsigned char)'-'].vals[0]
-#define        WACS_DARROW     _wacs_char[(unsigned char)'.'].vals[0]
-#define        WACS_BLOCK      _wacs_char[(unsigned char)'0'].vals[0]
-#define        WACS_DIAMOND    _wacs_char[(unsigned char)'`'].vals[0]
-#define        WACS_CKBOARD    _wacs_char[(unsigned char)'a'].vals[0]
-#define        WACS_DEGREE     _wacs_char[(unsigned char)'f'].vals[0]
-#define        WACS_PLMINUS    _wacs_char[(unsigned char)'g'].vals[0]
-#define        WACS_BOARD      _wacs_char[(unsigned char)'h'].vals[0]
-#define        WACS_LANTERN    _wacs_char[(unsigned char)'i'].vals[0]
-#define        WACS_LRCORNER   _wacs_char[(unsigned char)'j'].vals[0]
-#define        WACS_URCORNER   _wacs_char[(unsigned char)'k'].vals[0]
-#define        WACS_ULCORNER   _wacs_char[(unsigned char)'l'].vals[0]
-#define        WACS_LLCORNER   _wacs_char[(unsigned char)'m'].vals[0]
-#define        WACS_PLUS       _wacs_char[(unsigned char)'n'].vals[0]
-#define        WACS_HLINE      _wacs_char[(unsigned char)'q'].vals[0]
-#define        WACS_S1         _wacs_char[(unsigned char)'o'].vals[0]
-#define        WACS_S9         _wacs_char[(unsigned char)'s'].vals[0]
-#define        WACS_LTEE       _wacs_char[(unsigned char)'t'].vals[0]
-#define        WACS_RTEE       _wacs_char[(unsigned char)'u'].vals[0]
-#define        WACS_BTEE       _wacs_char[(unsigned char)'v'].vals[0]
-#define        WACS_TTEE       _wacs_char[(unsigned char)'w'].vals[0]
-#define        WACS_VLINE      _wacs_char[(unsigned char)'x'].vals[0]
-#define        WACS_BULLET     _wacs_char[(unsigned char)'~'].vals[0]
-#define        WACS_S3         _wacs_char[(unsigned char)'p'].vals[0]
-#define        WACS_S7         _wacs_char[(unsigned char)'r'].vals[0]
-#define        WACS_LEQUAL     _wacs_char[(unsigned char)'y'].vals[0]
-#define        WACS_GEQUAL     _wacs_char[(unsigned char)'z'].vals[0]
-#define        WACS_PI         _wacs_char[(unsigned char)'{'].vals[0]
-#define        WACS_NEQUAL     _wacs_char[(unsigned char)'|'].vals[0]
-#define        WACS_STERLING   _wacs_char[(unsigned char)'}'].vals[0]
+#define        WACS_RARROW     (&_wacs_char[(unsigned char)'+'])
+#define        WACS_LARROW     (&_wacs_char[(unsigned char)','])
+#define        WACS_UARROW     (&_wacs_char[(unsigned char)'-'])
+#define        WACS_DARROW     (&_wacs_char[(unsigned char)'.'])
+#define        WACS_BLOCK      (&_wacs_char[(unsigned char)'0'])
+#define        WACS_DIAMOND    (&_wacs_char[(unsigned char)'`'])
+#define        WACS_CKBOARD    (&_wacs_char[(unsigned char)'a'])
+#define        WACS_DEGREE     (&_wacs_char[(unsigned char)'f'])
+#define        WACS_PLMINUS    (&_wacs_char[(unsigned char)'g'])
+#define        WACS_BOARD      (&_wacs_char[(unsigned char)'h'])
+#define        WACS_LANTERN    (&_wacs_char[(unsigned char)'i'])
+#define        WACS_LRCORNER   (&_wacs_char[(unsigned char)'j'])
+#define        WACS_URCORNER   (&_wacs_char[(unsigned char)'k'])
+#define        WACS_ULCORNER   (&_wacs_char[(unsigned char)'l'])
+#define        WACS_LLCORNER   (&_wacs_char[(unsigned char)'m'])
+#define        WACS_PLUS       (&_wacs_char[(unsigned char)'n'])
+#define        WACS_HLINE      (&_wacs_char[(unsigned char)'q'])
+#define        WACS_S1         (&_wacs_char[(unsigned char)'o'])
+#define        WACS_S9         (&_wacs_char[(unsigned char)'s'])
+#define        WACS_LTEE       (&_wacs_char[(unsigned char)'t'])
+#define        WACS_RTEE       (&_wacs_char[(unsigned char)'u'])
+#define        WACS_BTEE       (&_wacs_char[(unsigned char)'v'])
+#define        WACS_TTEE       (&_wacs_char[(unsigned char)'w'])
+#define        WACS_VLINE      (&_wacs_char[(unsigned char)'x'])
+#define        WACS_BULLET     (&_wacs_char[(unsigned char)'~'])
+#define        WACS_S3         (&_wacs_char[(unsigned char)'p'])
+#define        WACS_S7         (&_wacs_char[(unsigned char)'r'])
+#define        WACS_LEQUAL     (&_wacs_char[(unsigned char)'y'])
+#define        WACS_GEQUAL     (&_wacs_char[(unsigned char)'z'])
+#define        WACS_PI         (&_wacs_char[(unsigned char)'{'])
+#define        WACS_NEQUAL     (&_wacs_char[(unsigned char)'|'])
+#define        WACS_STERLING   (&_wacs_char[(unsigned char)'}'])
 #endif /* HAVE_WCHAR */
 
 /* System V compatibility */
============================================================
--- lib/libcurses/ins_wch.c     f4b07b220495adb302495bab4e29b37dbdf5db22
+++ lib/libcurses/ins_wch.c     895654fbc4a088cb32a1f72a790c98016c7c7f64
@@ -110,6 +110,8 @@ wins_wch(WINDOW *win, const cchar_t *wch
        if ( !wch )
                return OK;
        cw = wcwidth(wch->vals[0]);
+       if (cw < 0)
+               cw = 1;
        if (!cw)
                return wadd_wch( win, wch );
 
============================================================
--- lib/libcurses/ins_wstr.c    d8e1c97327d0fd9f0463872aca91f1a4ec750ccc
+++ lib/libcurses/ins_wstr.c    193072eb1e6e1c7f4cbc7e5d2fcc12ae252d9289
@@ -144,6 +144,8 @@ wins_nwstr(WINDOW *win, const wchar_t *w
        if (!wstr)
                return OK;
        cw = wcwidth(*wstr);
+       if (cw < 0)
+               cw = 1;
        if (!cw)
                return ERR;
 
@@ -152,9 +154,13 @@ wins_nwstr(WINDOW *win, const wchar_t *w
        len = 1;
        n--;
        while (*scp) {
+               int w;
                if (!n)
                        break;
-               n--, len++, width += wcwidth(*scp);
+               w = wcwidth(*scp);
+               if (w < 0)
+                       w = 1;
+               n--, len++, width += w;
                scp++;
        }
 #ifdef DEBUG
@@ -267,6 +273,8 @@ wins_nwstr(WINDOW *win, const wchar_t *w
                                continue;
                }
                cw = wcwidth(*scp);
+               if (cw < 0)
+                       cw = 1;
                if (cw) {
                        /* 1st column */
                        temp1->ch = (wchar_t)*scp;
============================================================
--- lib/libcurses/line.c        15b60f8d9aaae4e76a14498d1f7550473c3d18c4
+++ lib/libcurses/line.c        e73017ae997ae8c5e85863c4eb243d475dd520bf
@@ -194,6 +194,8 @@ int whline_set(WINDOW *win, const cchar_
        cchar_t cc;
 
        cw = wcwidth( wch->vals[ 0 ]);
+       if (cw < 0)
+               cw = 1;
        if ( ( win->maxx - win->curx ) < cw )
                return ERR;
        wcn = min( n, ( win->maxx - win->curx ) / cw );
@@ -204,7 +206,7 @@ int whline_set(WINDOW *win, const cchar_
 
        memcpy( &cc, wch, sizeof( cchar_t ));
        if (!(wch->vals[ 0 ]))
-               cc.vals[ 0 ] |= WACS_HLINE;
+               cc.vals[ 0 ] |= WACS_HLINE->vals[0];
        for (i = 0; i < wcn; i++ ) {
 #ifdef DEBUG
                __CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
@@ -265,7 +267,7 @@ int wvline_set(WINDOW *win, const cchar_
 
        memcpy( &cc, wch, sizeof( cchar_t ));
        if (!(wch->vals[ 0 ]))
-               cc.vals[ 0 ] |= WACS_VLINE;
+               cc.vals[ 0 ] |= WACS_VLINE->vals[0];
        for (i = 0; i < wcn; i++) {
                mvwadd_wch(win, ocury + i, ocurx, &cc);
 #ifdef DEBUG


Home | Main Index | Thread Index | Old Index