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/703ae0953f41
branches: trunk
changeset: 354824:703ae0953f41
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 036dbe35edd9 -r 703ae0953f41 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 036dbe35edd9 -r 703ae0953f41 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 036dbe35edd9 -r 703ae0953f41 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 036dbe35edd9 -r 703ae0953f41 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