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