Module Name:    src
Committed By:   roy
Date:           Fri Feb 26 00:09:00 UTC 2010

Modified Files:
        src/lib/libterminfo: term.c term.h termcap.c terminfo.5.in

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/lib/libterminfo/term.c
cvs rdiff -u -r1.4 -r1.5 src/lib/libterminfo/term.h
cvs rdiff -u -r1.2 -r1.3 src/lib/libterminfo/termcap.c
cvs rdiff -u -r1.12 -r1.13 src/lib/libterminfo/terminfo.5.in

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libterminfo/term.c
diff -u src/lib/libterminfo/term.c:1.10 src/lib/libterminfo/term.c:1.11
--- src/lib/libterminfo/term.c:1.10	Mon Feb 22 23:05:39 2010
+++ src/lib/libterminfo/term.c	Fri Feb 26 00:09:00 2010
@@ -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;
 		}
 	}

Index: src/lib/libterminfo/term.h
diff -u src/lib/libterminfo/term.h:1.4 src/lib/libterminfo/term.h:1.5
--- src/lib/libterminfo/term.h:1.4	Thu Feb 11 00:27:09 2010
+++ src/lib/libterminfo/term.h	Fri Feb 26 00:09:00 2010
@@ -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

Index: src/lib/libterminfo/termcap.c
diff -u src/lib/libterminfo/termcap.c:1.2 src/lib/libterminfo/termcap.c:1.3
--- src/lib/libterminfo/termcap.c:1.2	Thu Feb  4 09:46:26 2010
+++ src/lib/libterminfo/termcap.c	Fri Feb 26 00:09:00 2010
@@ -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;
+		}
+
+		if (ip != info) {
+			*ip++ = ',';
+			*ip++ = ' ';
+		}
+
+		strcpy(ip, name);
+		ip += nl;
+		if (val != NULL) {
+			strcpy(ip, val);
+			ip += vl;
+			if (token[2] == '=')
+				free(val);
+		}
+	}
+
+	*ip = '\0';
+	return info;
+}
+

Index: src/lib/libterminfo/terminfo.5.in
diff -u src/lib/libterminfo/terminfo.5.in:1.12 src/lib/libterminfo/terminfo.5.in:1.13
--- src/lib/libterminfo/terminfo.5.in:1.12	Mon Feb 22 23:05:39 2010
+++ src/lib/libterminfo/terminfo.5.in	Fri Feb 26 00:09:00 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: terminfo.5.in,v 1.12 2010/02/22 23:05:39 roy Exp $
+.\"	$NetBSD: terminfo.5.in,v 1.13 2010/02/26 00:09:00 roy Exp $
 .\"
 .\" Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 22, 2010
+.Dd February 26, 2010
 .Dt TERMINFO 5
 .Os
 .Sh NAME
@@ -209,8 +209,16 @@
 then it is used.
 .Pp
 If the environment variable
+.Ev TERMCAP
+is available and does not begin with / then it will be translated into
+terminfo and compiled as above.
+If its name matches
+.Ev TERM
+then it is used.
+.Pp
+If the environment variable
 .Ev TERMINFO
-is available then and begins with / then only this file is searched.
+is available and begins with / then only this file is searched.
 Otherwise
 .Nm
 will first look for
@@ -248,3 +256,7 @@
 .Xr tic 1 .
 .Sh AUTHORS
 .An Roy Marples Aq r...@netbsd.org
+.Sh BUGS
+The
+.Ev TERMCAP
+capabilities %>, %B and %D are not converted into terminfo capabilities.

Reply via email to