Source-Changes-HG archive

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

[src/trunk]: src/lib/libedit Allow wide characters (properly encoded as byte ...



details:   https://anonhg.NetBSD.org/src/rev/25da3ed7d38d
branches:  trunk
changeset: 825125:25da3ed7d38d
user:      kre <kre%NetBSD.org@localhost>
date:      Fri Jun 30 20:26:52 2017 +0000

description:
Allow wide characters (properly encoded as byte strings according to LC_CTYPE)
to be (perhaps part of) the "invisible" characters in a prompt, or the
required prompt character which follows the literal sequence (this character
must be one with a printing column width >= 1).  The literal indicator
character (which is just a marker, and not printed anywhere) (the PSlit
parameter in sh(1)) can also be a wide char (passed to libedit as a wchar_t,
encoded as that by sh(1) or other applications that support this.)

Note: this has currently only been tested with everything ascii (C locale).

diffstat:

 lib/libedit/Makefile  |   3 +-
 lib/libedit/literal.c |  53 ++++++++++++++++++++++++++++++++++++++------------
 lib/libedit/literal.h |   4 +-
 lib/libedit/refresh.c |  18 ++++++++++++----
 4 files changed, 57 insertions(+), 21 deletions(-)

diffs (190 lines):

diff -r 0114d87f8c24 -r 25da3ed7d38d lib/libedit/Makefile
--- a/lib/libedit/Makefile      Fri Jun 30 18:28:31 2017 +0000
+++ b/lib/libedit/Makefile      Fri Jun 30 20:26:52 2017 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.64 2017/06/27 23:25:13 christos Exp $
+#      $NetBSD: Makefile,v 1.65 2017/06/30 20:26:52 kre Exp $
 #      @(#)Makefile    8.1 (Berkeley) 6/4/93
 
 USE_SHLIBDIR=  yes
@@ -133,6 +133,7 @@
 # XXX
 .if defined(HAVE_GCC)
 COPTS.editline.c+=     -Wno-cast-qual
+COPTS.literal.c+=      -Wno-sign-conversion
 COPTS.tokenizer.c+=    -Wno-cast-qual
 COPTS.tokenizern.c+=   -Wno-cast-qual
 .endif
diff -r 0114d87f8c24 -r 25da3ed7d38d lib/libedit/literal.c
--- a/lib/libedit/literal.c     Fri Jun 30 18:28:31 2017 +0000
+++ b/lib/libedit/literal.c     Fri Jun 30 20:26:52 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: literal.c,v 1.2 2017/06/29 02:54:40 kre Exp $  */
+/*     $NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $  */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include "config.h"
 #if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: literal.c,v 1.2 2017/06/29 02:54:40 kre Exp $");
+__RCSID("$NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $");
 #endif /* not lint && not SCCSID */
 
 /*
@@ -47,15 +47,14 @@
 literal_init(EditLine *el)
 {
        el_literal_t *l = &el->el_literal;
+
        memset(l, 0, sizeof(*l));
 }
 
 libedit_private void
 literal_end(EditLine *el)
 {
-       el_literal_t *l = &el->el_literal;
        literal_clear(el);
-       el_free(l->l_buf);
 }
 
 libedit_private void
@@ -63,33 +62,60 @@
 {
        el_literal_t *l = &el->el_literal;
        size_t i;
+
+       if (l->l_len == 0)
+               return;
+
        for (i = 0; i < l->l_idx; i++)
                el_free(l->l_buf[i]);
+       el_free(l->l_buf);
+       l->l_buf = NULL;
        l->l_len = 0;
        l->l_idx = 0;
 }
 
 libedit_private wint_t
-literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end)
+literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)
 {
-       // XXX: Only for narrow chars now.
        el_literal_t *l = &el->el_literal;
        size_t i, len;
+       ssize_t w, n;
        char *b;
 
+       w = wcwidth(end[1]);    /* column width of the visible char */
+       *wp = (int)w;
+
+       if (w <= 0)             /* we require something to be printed */
+               return 0;
+
        len = (size_t)(end - buf);
-       b = el_malloc(len + 2);
+       for (w = 0, i = 0; i < len; i++)
+               w += ct_enc_width(buf[i]);
+       w += ct_enc_width(end[1]);
+
+       b = el_malloc((size_t)(w + 1));
        if (b == NULL)
                return 0;
-       for (i = 0; i < len; i++)
-               b[i] = (char)buf[i];
-       b[len] = (char)end[1];
-       b[len + 1] = '\0';
+
+       for (n = 0, i = 0; i < len; i++)
+               n += ct_encode_char(b + n, w - n, buf[i]);
+       n += ct_encode_char(b + n, w - n, end[1]);
+       b[n] = '\0';
+
+       /*
+        * Then save this literal string in the list of such strings,
+        * and return a "magic character" to put into the terminal buffer.
+        * When that magic char is 'printed' the saved string (which includes
+        * the char that belongs in that position) gets sent instead.
+        */
        if (l->l_idx == l->l_len) {
-               l->l_len += 10;
-               char **bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
+               char **bp;
+
+               l->l_len += 4;
+               bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
                if (bp == NULL) {
                        free(b);
+                       l->l_len -= 4;
                        return 0;
                }
                l->l_buf = bp;
@@ -102,6 +128,7 @@
 literal_get(EditLine *el, wint_t idx)
 {
        el_literal_t *l = &el->el_literal;
+
        assert(idx & EL_LITERAL);
        idx &= ~EL_LITERAL;
        assert(l->l_idx > (size_t)idx);
diff -r 0114d87f8c24 -r 25da3ed7d38d lib/libedit/literal.h
--- a/lib/libedit/literal.h     Fri Jun 30 18:28:31 2017 +0000
+++ b/lib/libedit/literal.h     Fri Jun 30 20:26:52 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: literal.h,v 1.1 2017/06/27 23:25:13 christos Exp $     */
+/*     $NetBSD: literal.h,v 1.2 2017/06/30 20:26:52 kre Exp $  */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
 libedit_private void literal_end(EditLine *);
 libedit_private void literal_clear(EditLine *);
 libedit_private wint_t literal_add(EditLine *, const wchar_t *,
-    const wchar_t *);
+    const wchar_t *, int *);
 libedit_private const char *literal_get(EditLine *, wint_t);
 
 #endif /* _h_el_literal */
diff -r 0114d87f8c24 -r 25da3ed7d38d lib/libedit/refresh.c
--- a/lib/libedit/refresh.c     Fri Jun 30 18:28:31 2017 +0000
+++ b/lib/libedit/refresh.c     Fri Jun 30 20:26:52 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: refresh.c,v 1.53 2017/06/27 23:29:12 christos Exp $    */
+/*     $NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $ */
 
 /*-
  * Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)refresh.c  8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: refresh.c,v 1.53 2017/06/27 23:29:12 christos Exp $");
+__RCSID("$NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $");
 #endif
 #endif /* not lint && not SCCSID */
 
@@ -164,12 +164,20 @@
        coord_t *cur = &el->el_refresh.r_cursor;
        wint_t c;
        int sizeh = el->el_terminal.t_size.h;
+       int i, w;
 
-       c = literal_add(el, begin, end);
-       if (c == 0)
+       c = literal_add(el, begin, end, &w);
+       if (c == 0 || w <= 0)
                return;
        el->el_vdisplay[cur->v][cur->h] = c;
-       cur->h += 1;    /* XXX: only for narrow */
+
+       i = w;
+       if (i > sizeh - cur->h)         /* avoid overflow */
+               i = sizeh - cur->h;
+       while (--i > 0)
+               el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
+
+       cur->h += w;
        if (cur->h >= sizeh) {
                /* assure end of line */
                el->el_vdisplay[cur->v][sizeh] = '\0';



Home | Main Index | Thread Index | Old Index