Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libterminfo Implement captoinfo so that we can convert $...
details: https://anonhg.NetBSD.org/src/rev/a26ea7cb56ef
branches: trunk
changeset: 752443:a26ea7cb56ef
user: roy <roy%NetBSD.org@localhost>
date: Fri Feb 26 00:09:00 2010 +0000
description:
Implement captoinfo so that we can convert $TERMCAP into $TERMINFO.
We don't currently map %> %B %D.
That means no conversion for regent100, hz1500, act4, act5, mime terms.
diffstat:
lib/libterminfo/term.c | 66 +++++++++++++-
lib/libterminfo/term.h | 6 +-
lib/libterminfo/termcap.c | 179 +++++++++++++++++++++++++++++++++++++++++-
lib/libterminfo/terminfo.5.in | 18 +++-
4 files changed, 255 insertions(+), 14 deletions(-)
diffs (truncated from 365 to 300 lines):
diff -r 791ccaf4a0f1 -r a26ea7cb56ef lib/libterminfo/term.c
--- a/lib/libterminfo/term.c Fri Feb 26 00:01:27 2010 +0000
+++ b/lib/libterminfo/term.c Fri Feb 26 00:09:00 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: term.c,v 1.10 2010/02/22 23:05:39 roy Exp $ */
+/* $NetBSD: term.c,v 1.11 2010/02/26 00:09:00 roy Exp $ */
/*
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: term.c,v 1.10 2010/02/22 23:05:39 roy Exp $");
+__RCSID("$NetBSD: term.c,v 1.11 2010/02/26 00:09:00 roy Exp $");
#include <sys/stat.h>
@@ -283,6 +283,34 @@
}
static int
+ticcmp(const TIC *tic, const char *name)
+{
+ char *alias, *s;
+ size_t len, l;
+
+ if (strcmp(tic->name, name) == 0)
+ return 0;
+ if (tic->alias == NULL)
+ return -1;
+
+ len = strlen(name);
+ alias = tic->alias;
+ while (*alias != '\0') {
+ s = strchr(alias, '|');
+ if (s == NULL)
+ l = strlen(alias);
+ else
+ l = s - alias;
+ if (len == l && strncmp(alias, name, l) == 0)
+ return 0;
+ if (s == NULL)
+ break;
+ alias = s + 1;
+ }
+ return 1;
+}
+
+static int
_ti_findterm(TERMINAL *term, const char *name, int flags)
{
int r;
@@ -298,13 +326,32 @@
_ti_database = NULL;
r = 0;
- if ((e = getenv("TERMINFO")) != NULL && *e != '\0') {
+ if ((e = getenv("TERMINFO")) != NULL && *e != '\0')
if (e[0] == '/')
return _ti_dbgetterm(term, e, name, flags);
- c = strdup(e); /* So we don't destroy env */
- tic = _ti_compile(c, TIC_WARNING | TIC_EXTRA);
- free(c);
- if (tic != NULL && strcmp(tic->name, name) == 0) {
+
+ c = NULL;
+ if (e == NULL && (c = getenv("TERMCAP")) != NULL) {
+ if (*c != '\0' && *c != '/') {
+ c = strdup(c);
+ if (c != NULL) {
+ e = captoinfo(c);
+ free(c);
+ }
+ }
+ }
+
+ if (e != NULL) {
+ if (c == NULL)
+ e = strdup(e); /* So we don't destroy env */
+ if (e == NULL)
+ tic = NULL;
+ else
+ tic = _ti_compile(e, TIC_WARNING |
+ TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
+ if (c == NULL && e != NULL)
+ free(e);
+ if (tic != NULL && ticcmp(tic, name) == 0) {
len = _ti_flatten(&f, tic);
if (len != -1) {
r = _ti_readterm(term, (char *)f, len, flags);
@@ -313,7 +360,10 @@
}
_ti_freetic(tic);
if (r == 1) {
- _ti_database = "$TERMINFO";
+ if (c == NULL)
+ _ti_database = "$TERMINFO";
+ else
+ _ti_database = "$TERMCAP";
return r;
}
}
diff -r 791ccaf4a0f1 -r a26ea7cb56ef lib/libterminfo/term.h
--- a/lib/libterminfo/term.h Fri Feb 26 00:01:27 2010 +0000
+++ b/lib/libterminfo/term.h Fri Feb 26 00:09:00 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: term.h,v 1.4 2010/02/11 00:27:09 roy Exp $ */
+/* $NetBSD: term.h,v 1.5 2010/02/26 00:09:00 roy Exp $ */
/*
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -1512,5 +1512,9 @@
# define t_parm t_vtparm
#endif
+/* Convert a termcap string into a terminfo string.
+ * The passed string is destroyed and the return string needs to be freed. */
+char * captoinfo(char *);
+
__END_DECLS
#endif
diff -r 791ccaf4a0f1 -r a26ea7cb56ef lib/libterminfo/termcap.c
--- a/lib/libterminfo/termcap.c Fri Feb 26 00:01:27 2010 +0000
+++ b/lib/libterminfo/termcap.c Fri Feb 26 00:09:00 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: termcap.c,v 1.2 2010/02/04 09:46:26 roy Exp $ */
+/* $NetBSD: termcap.c,v 1.3 2010/02/26 00:09:00 roy Exp $ */
/*
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -28,9 +28,11 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: termcap.c,v 1.2 2010/02/04 09:46:26 roy Exp $");
+__RCSID("$NetBSD: termcap.c,v 1.3 2010/02/26 00:09:00 roy Exp $");
#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <term_private.h>
@@ -180,3 +182,176 @@
_DIAGASSERT(cm != NULL);
return vtparm(cm, destline, destcol);
}
+
+static const char *
+flagname(const char *key)
+{
+ uint32_t idx;
+
+ idx = _t_flaghash((const unsigned char *)key, strlen(key));
+ if (idx <= __arraycount(_ti_cap_flagids) &&
+ strcmp(key, _ti_cap_flagids[idx].id) == 0)
+ return _ti_flagid(_ti_cap_flagids[idx].ti);
+ return key;
+}
+
+static const char *
+numname(const char *key)
+{
+ uint32_t idx;
+
+ idx = _t_numhash((const unsigned char *)key, strlen(key));
+ if (idx <= __arraycount(_ti_cap_numids) &&
+ strcmp(key, _ti_cap_numids[idx].id) == 0)
+ return _ti_numid(_ti_cap_numids[idx].ti);
+ return key;
+}
+
+static const char *
+strname(const char *key)
+{
+ uint32_t idx;
+
+ idx = _t_strhash((const unsigned char *)key, strlen(key));
+ if (idx <= __arraycount(_ti_cap_strids) &&
+ strcmp(key, _ti_cap_strids[idx].id) == 0)
+ return _ti_strid(_ti_cap_strids[idx].ti);
+
+ if (strcmp(key, "tc") == 0)
+ return "use";
+
+ return key;
+}
+
+/* We don't currently map %> %B %D
+ * That means no conversion for regent100, hz1500, act4, act5, mime terms. */
+static char *
+strval(const char *val)
+{
+ char *info, *ip, c;
+ int p;
+ size_t len, l, n;
+
+ len = 1024; /* no single string should be bigger */
+ info = ip = malloc(len);
+ if (info == NULL)
+ return 0;
+
+ l = 0;
+ p = 1;
+ for (; *val != '\0'; val++) {
+ if (l + 2 > len)
+ goto elen;
+ if (*val != '%') {
+ *ip++ = *val;
+ l++;
+ continue;
+ }
+ switch (c = *(++val)) {
+ case 'd':
+ if (l + 6 > len)
+ goto elen;
+ *ip++ = '%';
+ *ip++ = 'p';
+ *ip++ = '0' + p;
+ *ip++ = '%';
+ *ip++ = 'd';
+ l += 5;
+ n += 5;
+ /* FALLTHROUGH */
+ case 'r':
+ p = 3 - p;
+ break;
+ default:
+ /* Hope it matches a terminfo command. */
+ *ip++ = '%';
+ *ip++ = c;
+ l += 2;
+ break;
+ }
+ }
+
+ *ip = '\0';
+ return info;
+
+elen:
+ free(info);
+ errno = ENOMEM;
+ return NULL;
+}
+
+char *
+captoinfo(char *cap)
+{
+ char *info, *ip, *token, *val, *p, tok[3];
+ const char *name;
+ size_t len, lp, nl, vl, rl;
+
+ _DIAGASSERT(cap != NULL);
+
+ len = strlen(cap) * 2;
+ info = ip = malloc(len);
+ if (info == NULL)
+ return NULL;
+
+ lp = 0;
+ tok[2] = '\0';
+ while ((token = strsep(&cap, ":")) != NULL) {
+ /* Trim whitespace */
+ while (isspace((unsigned char)*token))
+ token++;
+ if (token[0] == '\0')
+ continue;
+ name = token;
+ val = NULL;
+ if (token[1] != '\0') {
+ tok[0] = token[0];
+ tok[1] = token[1];
+ if (token[2] == '\0') {
+ name = flagname(tok);
+ val = NULL;
+ } else if (token[2] == '#') {
+ name = numname(tok);
+ val = token + 2;
+ } else if (token[2] == '=') {
+ name = strname(tok);
+ val = strval(token + 2);
+ }
+ }
+ nl = strlen(name);
+ if (val == NULL)
+ vl = 0;
+ else
+ vl = strlen(val);
+ rl = nl + vl + 3; /* , \0 */
+
+ if (lp + rl > len) {
+ if (rl < 256)
+ len += 256;
+ else
+ len += rl;
+ p = realloc(info, len);
+ if (p == NULL)
+ return NULL;
+ info = p;
Home |
Main Index |
Thread Index |
Old Index