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.
This commit is contained in:
parent
51d6f75dc3
commit
007ba6f7e2
@ -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>
|
||||
|
||||
@ -282,6 +282,34 @@ _ti_dbgettermp(TERMINAL *term, const char *path, const char *name, int flags)
|
||||
return e;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -298,13 +326,32 @@ _ti_findterm(TERMINAL *term, const char *name, int flags)
|
||||
_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_findterm(TERMINAL *term, const char *name, int flags)
|
||||
}
|
||||
_ti_freetic(tic);
|
||||
if (r == 1) {
|
||||
_ti_database = "$TERMINFO";
|
||||
if (c == NULL)
|
||||
_ti_database = "$TERMINFO";
|
||||
else
|
||||
_ti_database = "$TERMCAP";
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ char * t_vparm(TERMINAL *, const char *, ...);
|
||||
# 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
|
||||
|
@ -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 @@ tgoto(const char *cm, int destcol, int destline)
|
||||
_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;
|
||||
}
|
||||
|
||||
|
@ -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 @@ whose name matches
|
||||
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 @@ Extensions to the standard are noted in
|
||||
.Xr tic 1 .
|
||||
.Sh AUTHORS
|
||||
.An Roy Marples Aq roy@NetBSD.org
|
||||
.Sh BUGS
|
||||
The
|
||||
.Ev TERMCAP
|
||||
capabilities %>, %B and %D are not converted into terminfo capabilities.
|
||||
|
Loading…
Reference in New Issue
Block a user