Use _ti_get_token instead of strsep when parsing termcap entries.

This allows us to handle \E\ as a valid sequence.
This commit is contained in:
roy 2010-03-02 14:11:11 +00:00
parent 9cbe93a0cc
commit 4b2d6106cf
3 changed files with 37 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: compile.c,v 1.3 2010/03/01 01:59:48 dholland Exp $ */
/* $NetBSD: compile.c,v 1.4 2010/03/02 14:11:11 roy Exp $ */
/*
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@ -32,7 +32,7 @@
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: compile.c,v 1.3 2010/03/01 01:59:48 dholland Exp $");
__RCSID("$NetBSD: compile.c,v 1.4 2010/03/02 14:11:11 roy Exp $");
#if !HAVE_NBTOOL_CONFIG_H || HAVE_SYS_ENDIAN_H
#include <sys/endian.h>
@ -413,11 +413,10 @@ encode_string(const char *term, const char *cap, TBUF *tbuf, const char *str,
return 0;
}
static char *
get_token(char **cap)
char *
_ti_get_token(char **cap, char sep)
{
char *token;
int esc;
char esc, *token;
while (isspace((unsigned char)**cap))
(*cap)++;
@ -425,16 +424,21 @@ get_token(char **cap)
return NULL;
/* We can't use stresep(3) as ^ we need two escape chars */
esc = 0;
esc = '\0';
for (token = *cap;
**cap != '\0' && (esc == 1 || **cap != ',');
**cap != '\0' && (esc != '\0' || **cap != sep);
(*cap)++)
{
if (esc == 0) {
if (esc == '\0') {
if (**cap == '\\' || **cap == '^')
esc = 1;
} else
esc = 0;
esc = **cap;
} else {
/* termcap /E/ is valid */
if (sep == ':' && esc == '\\' && **cap == 'E')
esc = 'x';
else
esc = '\0';
}
}
if (**cap != '\0')
@ -456,7 +460,7 @@ _ti_compile(char *cap, int flags)
_DIAGASSERT(cap != NULL);
name = get_token(&cap);
name = _ti_get_token(&cap, ',');
if (name == NULL) {
dowarn(flags, "no seperator found: %s", cap);
return NULL;
@ -489,9 +493,9 @@ _ti_compile(char *cap, int flags)
goto error;
}
for (token = get_token(&cap);
for (token = _ti_get_token(&cap, ',');
token != NULL && *token != '\0';
token = get_token(&cap))
token = _ti_get_token(&cap, ','))
{
/* Skip commented caps */
if (!(flags & TIC_COMMENT) && token[0] == '.')

View File

@ -1,4 +1,4 @@
/* $NetBSD: term_private.h,v 1.6 2010/02/22 23:05:39 roy Exp $ */
/* $NetBSD: term_private.h,v 1.7 2010/03/02 14:11:11 roy Exp $ */
/*
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@ -143,6 +143,7 @@ typedef struct tic {
} TIC;
char *_ti_grow_tbuf(TBUF *, size_t);
char *_ti_get_token(char **, char);
char *_ti_find_cap(TBUF *, char, short);
char *_ti_find_extra(TBUF *, const char *);
size_t _ti_store_extra(TIC *, int, char *, char, char, short,

View File

@ -1,4 +1,4 @@
/* $NetBSD: termcap.c,v 1.4 2010/03/01 11:02:31 roy Exp $ */
/* $NetBSD: termcap.c,v 1.5 2010/03/02 14:11:11 roy Exp $ */
/*
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: termcap.c,v 1.4 2010/03/01 11:02:31 roy Exp $");
__RCSID("$NetBSD: termcap.c,v 1.5 2010/03/02 14:11:11 roy Exp $");
#include <assert.h>
#include <ctype.h>
@ -277,6 +277,16 @@ strval(const char *val)
}
}
/* \E\ is valid termcap.
* We need to escape the final \ for terminfo. */
if (l > 2 && info[l - 1] == '\\' &&
(info[l - 2] != '\\' && info[l - 2] != '^'))
{
if (l + 1 > len)
goto elen;
*ip++ = '\\';
}
*ip = '\0';
return info;
@ -302,10 +312,10 @@ captoinfo(char *cap)
lp = 0;
tok[2] = '\0';
while ((token = strsep(&cap, ":")) != NULL) {
/* Trim whitespace */
while (isspace((unsigned char)*token))
token++;
for (token = _ti_get_token(&cap, ':');
token != NULL;
token = _ti_get_token(&cap, ':'))
{
if (token[0] == '\0')
continue;
name = token;