Redo the conflict calculation (again).

Assume that "me" clears all attributes apart from acs.
Problem noticed when working on window(1).
This commit is contained in:
jdc 2003-02-02 17:54:38 +00:00
parent a2441aa437
commit ea7837ba99
1 changed files with 89 additions and 37 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: setterm.c,v 1.35 2003/01/27 21:12:29 jdc Exp $ */
/* $NetBSD: setterm.c,v 1.36 2003/02/02 17:54:38 jdc Exp $ */
/*
* Copyright (c) 1981, 1993, 1994
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)setterm.c 8.8 (Berkeley) 10/25/94";
#else
__RCSID("$NetBSD: setterm.c,v 1.35 2003/01/27 21:12:29 jdc Exp $");
__RCSID("$NetBSD: setterm.c,v 1.36 2003/02/02 17:54:38 jdc Exp $");
#endif
#endif /* not lint */
@ -55,6 +55,7 @@ __RCSID("$NetBSD: setterm.c,v 1.35 2003/01/27 21:12:29 jdc Exp $");
static int zap(SCREEN *screen);
static int does_esc_m(char *cap);
static int does_ctrl_o(char *cap);
struct tinfo *_cursesi_genbuf;
@ -243,23 +244,16 @@ _cursesi_setterm(char *type, SCREEN *screen)
screen->mask_op &= ~__TERMATTR;
}
}
screen->mask_me = __ATTRIBUTES & ~__TERMATTR;
if (screen->tc_me != NULL) {
if (does_esc_m(screen->tc_me))
screen->mask_me &=
~(__STANDOUT | __UNDERSCORE | __COLOR);
else {
if (screen->tc_se != NULL &&
!strcmp(screen->tc_me, screen->tc_se))
screen->mask_me &= ~__STANDOUT;
if (screen->tc_ue != NULL &&
!strcmp(screen->tc_me, screen->tc_ue))
screen->mask_me &= ~__UNDERSCORE;
if (screen->tc_op != NULL &&
!strcmp(screen->tc_me, screen->tc_op))
screen->mask_me &= ~__COLOR;
}
}
/*
* Assume that "me" turns off all attributes apart from ACS.
* It might turn off ACS, so check for that.
*/
if (screen->tc_me != NULL && does_ctrl_o(screen->tc_me))
screen->mask_me = 0;
else
screen->mask_me = __ALTCHARSET;
/* Check what turning off the attributes also turns off */
screen->mask_ue = __ATTRIBUTES & ~__UNDERSCORE;
if (screen->tc_ue != NULL) {
if (does_esc_m(screen->tc_ue))
@ -281,7 +275,7 @@ _cursesi_setterm(char *type, SCREEN *screen)
if (screen->tc_se != NULL) {
if (does_esc_m(screen->tc_se))
screen->mask_se &=
~(__UNDERSCORE | __TERMATTR | __COLOR);
~(__UNDERSCORE | __TERMATTR | __COLOR);
else {
if (screen->tc_ue != NULL &&
!strcmp(screen->tc_se, screen->tc_ue))
@ -437,34 +431,92 @@ getcap(char *name)
* other attributes, so we check for this in the capability passed to us.
* Note that we can't just do simple string comparison, as the capability
* may contain multiple, ';' separated sequence parts.
*
*/
static int
does_esc_m(char *cap)
{
#define CAP_LEN 253 /* termcap capability size - 3 */
char parts[CAP_LEN];
size_t len;
char *part;
const char *sep = ";";
#define WAITING 0
#define PARSING 1
#define NUMBER 2
#define FOUND 4
char *capptr;
int seq;
#ifdef DEBUG
__CTRACE("does_esc_m: Checking %s\n", cap);
#endif
/* Is it just "\E[m" or "\E[0m"? */
if (!strcmp(cap, "\x1b[m") || !strcmp(cap, "\x1b[0m"))
return 1;
/* Does it start "\E[" and end with "m"? */
if (strlen(cap) > 3 && cap[0] == '\x1b' && cap[1] == '[' &&
cap[strlen(cap) - 1] == 'm') {
/* Check for a '0' between the ';'s */
len=strlen(cap);
strlcpy(parts, &cap[2],
len - 2 > CAP_LEN ? CAP_LEN : len - 2);
part=strtok(parts, sep);
while (part != NULL) {
if (!strcmp(part, "0"))
/* Does it contain a "\E[...m" sequence? */
if (strlen(cap) < 4)
return 0;
capptr = cap;
seq = WAITING;
while (*capptr != NULL) {
switch (seq) {
/* Start of sequence */
case WAITING:
if (!strncmp(capptr, "\x1b[", 2)) {
capptr+=2;
if (*capptr == 'm')
return 1;
else {
seq=PARSING;
continue;
}
}
break;
/* Looking for '0' */
case PARSING:
if (*capptr == '0')
seq=FOUND;
else if (*capptr > '0' && *capptr <= '9')
seq=NUMBER;
else if (*capptr != ';')
seq=WAITING;
break;
/* Some other number */
case NUMBER:
if (*capptr == ';')
seq=PARSING;
else if (!(*capptr >= '0' && *capptr <= '9'))
seq=WAITING;
break;
/* Found a '0' */
case FOUND:
if (*capptr == 'm')
return 1;
part=strtok(NULL, "0");
else if (!((*capptr >= '0' && *capptr <= '9') ||
*capptr == ';'))
seq=WAITING;
break;
default:
break;
}
capptr++;
}
return 0;
}
/*
* does_ctrl_o --
* A hack for vt100/xterm-like terminals where the "me" capability also
* unsets acs (i.e. it contains the character '\017').
*/
static int
does_ctrl_o(char *cap)
{
char *capptr = cap;
#ifdef DEBUG
__CTRACE("does_ctrl_o: Looping on %s\n", capptr);
#endif
while (*capptr != NULL) {
if (*capptr == '\x0f')
return 1;
capptr++;
}
return 0;
}