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 [email protected]
+.Sh BUGS
+The
+.Ev TERMCAP
+capabilities %>, %B and %D are not converted into terminfo capabilities.