Example #1
0
static int capcmp(const char *s, const char *t)
/* capability comparison function */
{
    if (!VALID_STRING(s) && !VALID_STRING(t))
	return(0);
    else if (!VALID_STRING(s) || !VALID_STRING(t))
	return(1);

    if (ignorepads)
	return(_nc_capcmp(s, t));
    else
	return(strcmp(s, t));
}
Example #2
0
static int
capcmp(PredIdx idx, const char *s, const char *t)
/* capability comparison function */
{
    if (!VALID_STRING(s) && !VALID_STRING(t))
	return (s != t);
    else if (!VALID_STRING(s) || !VALID_STRING(t))
	return (1);

    if ((idx == acs_chars_index) || !ignorepads)
	return (strcmp(s, t));
    else
	return (_nc_capcmp(s, t));
}
static void
postprocess_termcap(TERMTYPE * tp, bool has_base)
{
    char buf[MAX_LINE * 2 + 2];
    string_desc result;

    /*
     * TERMCAP DEFAULTS AND OBSOLETE-CAPABILITY TRANSLATIONS
     *
     * This first part of the code is the functional inverse of the
     * fragment in capdefaults.c.
     * ----------------------------------------------------------------------
     */

    /* if there was a tc entry, assume we picked up defaults via that */
    if (!has_base) {
	if (WANTED(init_3string) && termcap_init2)
	    init_3string = _nc_save_str(termcap_init2);

	if (WANTED(reset_2string) && termcap_reset)
	    reset_2string = _nc_save_str(termcap_reset);

	if (WANTED(carriage_return)) {
	    if (carriage_return_delay > 0) {
		sprintf(buf, "%s$<%d>", C_CR, carriage_return_delay);
		carriage_return = _nc_save_str(buf);
	    } else
		carriage_return = _nc_save_str(C_CR);
	}
	if (WANTED(cursor_left)) {
	    if (backspace_delay > 0) {
		sprintf(buf, "%s$<%d>", C_BS, backspace_delay);
		cursor_left = _nc_save_str(buf);
	    } else if (backspaces_with_bs == 1)
		cursor_left = _nc_save_str(C_BS);
	    else if (PRESENT(backspace_if_not_bs))
		cursor_left = backspace_if_not_bs;
	}
	/* vi doesn't use "do", but it does seems to use nl (or '\n') instead */
	if (WANTED(cursor_down)) {
	    if (PRESENT(linefeed_if_not_lf))
		cursor_down = linefeed_if_not_lf;
	    else if (linefeed_is_newline != 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    cursor_down = _nc_save_str(buf);
		} else
		    cursor_down = _nc_save_str(C_LF);
	    }
	}
	if (WANTED(scroll_forward) && crt_no_scrolling != 1) {
	    if (PRESENT(linefeed_if_not_lf))
		cursor_down = linefeed_if_not_lf;
	    else if (linefeed_is_newline != 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    scroll_forward = _nc_save_str(buf);
		} else
		    scroll_forward = _nc_save_str(C_LF);
	    }
	}
	if (WANTED(newline)) {
	    if (linefeed_is_newline == 1) {
		if (new_line_delay > 0) {
		    sprintf(buf, "%s$<%d>", C_LF, new_line_delay);
		    newline = _nc_save_str(buf);
		} else
		    newline = _nc_save_str(C_LF);
	    } else if (PRESENT(carriage_return) && PRESENT(scroll_forward)) {
		_nc_str_init(&result, buf, sizeof(buf));
		if (_nc_safe_strcat(&result, carriage_return)
		 && _nc_safe_strcat(&result, scroll_forward))
		    newline = _nc_save_str(buf);
	    } else if (PRESENT(carriage_return) && PRESENT(cursor_down)) {
		_nc_str_init(&result, buf, sizeof(buf));
		if (_nc_safe_strcat(&result, carriage_return)
		 && _nc_safe_strcat(&result, cursor_down))
		    newline = _nc_save_str(buf);
	    }
	}
    }

    /*
     * Inverse of capdefaults.c code ends here.
     * ----------------------------------------------------------------------
     *
     * TERMCAP-TO TERMINFO MAPPINGS FOR SOURCE TRANSLATION
     *
     * These translations will *not* be inverted by tgetent().
     */

    if (!has_base) {
	/*
	 * We wait until now to decide if we've got a working cr because even
	 * one that doesn't work can be used for newline. Unfortunately the
	 * space allocated for it is wasted.
	 */
	if (return_does_clr_eol == 1 || no_correctly_working_cr == 1)
	    carriage_return = ABSENT_STRING;

	/*
	 * Supposedly most termcap entries have ta now and '\t' is no longer a
	 * default, but it doesn't seem to be true...
	 */
	if (WANTED(tab)) {
	    if (horizontal_tab_delay > 0) {
		sprintf(buf, "%s$<%d>", C_HT, horizontal_tab_delay);
		tab = _nc_save_str(buf);
	    } else
		tab = _nc_save_str(C_HT);
	}
	if (init_tabs == ABSENT_NUMERIC && has_hardware_tabs == TRUE)
	    init_tabs = 8;

	/*
	 * Assume we can beep with ^G unless we're given bl@.
	 */
	if (WANTED(bell))
	    bell = _nc_save_str("\007");
    }

    /*
     * Translate the old termcap :pt: capability to it#8 + ht=\t
     */
    if (has_hardware_tabs == TRUE) {
	if (init_tabs != 8 && init_tabs != ABSENT_NUMERIC)
	    _nc_warning("hardware tabs with a width other than 8: %d", init_tabs);
	else {
	    if (tab && _nc_capcmp(tab, C_HT))
		_nc_warning("hardware tabs with a non-^I tab string %s",
			    _nc_visbuf(tab));
	    else {
		if (WANTED(tab))
		    tab = _nc_save_str(C_HT);
		init_tabs = 8;
	    }
	}
    }
    /*
     * Now translate the ko capability, if there is one.  This
     * isn't from mytinfo...
     */
    if (PRESENT(other_non_function_keys)) {
	char *base = other_non_function_keys;
	char *bp, *cp, *dp;
	struct name_table_entry const *from_ptr;
	struct name_table_entry const *to_ptr;
	assoc const *ap;
	char buf2[MAX_TERMINFO_LENGTH];
	bool foundim;

	/* we're going to use this for a special case later */
	dp = strchr(other_non_function_keys, 'i');
	foundim = (dp != 0) && (dp[1] == 'm');

	/* look at each comma-separated capability in the ko string... */
	for (base = other_non_function_keys;
	     (cp = strchr(base, ',')) != 0;
	     base = cp + 1) {
	    size_t len = cp - base;

	    for (ap = ko_xlate; ap->from; ap++)
		if (len == strlen(ap->from)
		    && strncmp(ap->from, base, len) == 0)
		    break;
	    if (!ap->to) {
		_nc_warning("unknown capability `%.*s' in ko string",
			    (int) len, base);
		continue;
	    } else if (ap->to == CANCELLED_STRING)	/* ignore it */
		continue;

	    /* now we know we found a match in ko_table, so... */

	    from_ptr = _nc_find_entry(ap->from, _nc_cap_hash_table);
	    to_ptr = _nc_find_entry(ap->to, _nc_info_hash_table);

	    if (!from_ptr || !to_ptr)	/* should never happen! */
		_nc_err_abort("ko translation table is invalid, I give up");

	    if (WANTED(tp->Strings[from_ptr->nte_index])) {
		_nc_warning("no value for ko capability %s", ap->from);
		continue;
	    }

	    if (tp->Strings[to_ptr->nte_index]) {
		/* There's no point in warning about it if it's the same
		 * string; that's just an inefficiency.
		 */
		if (strcmp(
			      tp->Strings[from_ptr->nte_index],
			      tp->Strings[to_ptr->nte_index]) != 0)
		    _nc_warning("%s (%s) already has an explicit value %s, ignoring ko",
				ap->to, ap->from,
				_nc_visbuf(tp->Strings[to_ptr->nte_index]));
		continue;
	    }

	    /*
	     * The magic moment -- copy the mapped key string over,
	     * stripping out padding.
	     */
	    for (dp = buf2, bp = tp->Strings[from_ptr->nte_index]; *bp; bp++) {
		if (bp[0] == '$' && bp[1] == '<') {
		    while (*bp && *bp != '>') {
			++bp;
		    }
		} else
		    *dp++ = *bp;
	    }
	    *dp++ = '\0';

	    tp->Strings[to_ptr->nte_index] = _nc_save_str(buf2);
	}

	/*
	 * Note: ko=im and ko=ic both want to grab the `Insert'
	 * keycap.  There's a kich1 but no ksmir, so the ic capability
	 * got mapped to kich1 and im to kIC to avoid a collision.
	 * If the description has im but not ic, hack kIC back to kich1.
	 */
	if (foundim && WANTED(key_ic) && key_sic) {
	    key_ic = key_sic;
	    key_sic = ABSENT_STRING;
	}
    }

    if (!hard_copy) {
	if (WANTED(key_backspace))
	    key_backspace = _nc_save_str(C_BS);
	if (WANTED(key_left))
	    key_left = _nc_save_str(C_BS);
	if (WANTED(key_down))
	    key_down = _nc_save_str(C_LF);
    }

    /*
     * Translate XENIX forms characters.
     */
    if (PRESENT(acs_ulcorner) ||
	PRESENT(acs_llcorner) ||
	PRESENT(acs_urcorner) ||
	PRESENT(acs_lrcorner) ||
	PRESENT(acs_ltee) ||
	PRESENT(acs_rtee) ||
	PRESENT(acs_btee) ||
	PRESENT(acs_ttee) ||
	PRESENT(acs_hline) ||
	PRESENT(acs_vline) ||
	PRESENT(acs_plus)) {
	char buf2[MAX_TERMCAP_LENGTH];

	_nc_str_init(&result, buf2, sizeof(buf2));
	_nc_safe_strcat(&result, acs_chars);

	append_acs (&result, 'j', acs_lrcorner);
	append_acs (&result, 'k', acs_urcorner);
	append_acs (&result, 'l', acs_ulcorner);
	append_acs (&result, 'm', acs_llcorner);
	append_acs (&result, 'n', acs_plus);
	append_acs (&result, 'q', acs_hline);
	append_acs (&result, 't', acs_ltee);
	append_acs (&result, 'u', acs_rtee);
	append_acs (&result, 'v', acs_btee);
	append_acs (&result, 'w', acs_ttee);
	append_acs (&result, 'x', acs_vline);

	if (buf2[0]) {
	    acs_chars = _nc_save_str(buf2);
	    _nc_warning("acsc string synthesized from XENIX capabilities");
	}
    } else if (acs_chars == 0
	       && enter_alt_charset_mode != 0
	       && exit_alt_charset_mode != 0) {
	acs_chars =
	    _nc_save_str("``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~");
    }
}
Example #4
0
static void analyze_string(const char *name, const char *cap, TERMTYPE *tp)
{
    char	buf[MAX_TERMINFO_LENGTH];
    char	buf2[MAX_TERMINFO_LENGTH];
    const char	*sp, *ep;
    const assoc	*ap;

    if (cap == ABSENT_STRING || cap == CANCELLED_STRING)
	return;
    (void) printf("%s: ", name);

    buf[0] = '\0';
    for (sp = cap; *sp; sp++)
    {
	int	i;
	size_t	len = 0;
	const char *expansion = 0;

	/* first, check other capabilities in this entry */
	for (i = 0; i < STRCOUNT; i++)
	{
	    char	*cp = tp->Strings[i];

	    /* don't use soft-key capabilities */
	    if (strnames[i][0] == 'k' && strnames[i][0] == 'f')
		continue;


	    if (cp != ABSENT_STRING && cp != CANCELLED_STRING && cp[0] && cp != cap)
	    {
		len = strlen(cp);
		(void) strncpy(buf2, sp, len);
		buf2[len] = '\0';

		if (_nc_capcmp(cp, buf2))
		    continue;

#define ISRS(s)	(!strncmp((s), "is", 2) || !strncmp((s), "rs", 2))
		/*
		 * Theoretically we just passed the test for translation
		 * (equality once the padding is stripped).  However, there
		 * are a few more hoops that need to be jumped so that
		 * identical pairs of initialization and reset strings
		 * don't just refer to each other.
		 */
		if (ISRS(name) || ISRS(strnames[i]))
		    if (cap < cp)
			continue;
#undef ISRS

		expansion = strnames[i];
		break;
	    }
	}

	/* now check the standard capabilities */
	if (!expansion)
	    for (ap = std_caps; ap->from; ap++)
	    {
		len = strlen(ap->from);

		if (strncmp(ap->from, sp, len) == 0)
		{
		    expansion = ap->to;
		    break;
		}
	    }

	/* now check for private-mode sequences */
	if (!expansion
		    && sp[0] == '\033' && sp[1] == '[' && sp[2] == '?'
		    && (len = strspn(sp + 3, "0123456789;"))
		    && ((sp[3 + len] == 'h') || (sp[3 + len] == 'l')))
	{
	    char	buf3[MAX_TERMINFO_LENGTH];

	    (void) strcpy(buf2, (sp[3 + len] == 'h') ? "DEC+" : "DEC-");
	    (void) strncpy(buf3, sp + 3, len);
	    len += 4;
	    buf3[len] = '\0';

	    ep = strtok(buf3, ";");
	    do {
		   bool	found = FALSE;

		   for (ap = private_modes; ap->from; ap++)
		   {
		       size_t tlen = strlen(ap->from);

		       if (strncmp(ap->from, ep, tlen) == 0)
		       {
			   (void) strcat(buf2, ap->to);
			   found = TRUE;
			   break;
		       }
		   }

		   if (!found)
		       (void) strcat(buf2, ep);
		   (void) strcat(buf2, ";");
	       } while
		   ((ep = strtok((char *)NULL, ";")));
	    buf2[strlen(buf2) - 1] = '\0';
	    expansion = buf2;
	}

	/* now check for ECMA highlight sequences */
	if (!expansion
		    && sp[0] == '\033' && sp[1] == '['
		    && (len = strspn(sp + 2, "0123456789;"))
		    && sp[2 + len] == 'm')
	{
	    char	buf3[MAX_TERMINFO_LENGTH];

	    (void) strcpy(buf2, "SGR:");
	    (void) strncpy(buf3, sp + 2, len);
	    len += 3;
	    buf3[len] = '\0';

	    ep = strtok(buf3, ";");
	    do {
		   bool	found = FALSE;

		   for (ap = ecma_highlights; ap->from; ap++)
		   {
		       size_t tlen = strlen(ap->from);

		       if (strncmp(ap->from, ep, tlen) == 0)
		       {
			   (void) strcat(buf2, ap->to);
			   found = TRUE;
			   break;
		       }
		   }

		   if (!found)
		       (void) strcat(buf2, ep);
		   (void) strcat(buf2, ";");
	       } while
		   ((ep = strtok((char *)NULL, ";")));

	    buf2[strlen(buf2) - 1] = '\0';
	    expansion = buf2;
	}
	/* now check for scroll region reset */
	if (!expansion)
	{
	    (void) sprintf(buf2, "\033[1;%dr", tp->Numbers[2]);
	    len = strlen(buf2);
	    if (strncmp(buf2, sp, len) == 0)
		expansion = "RSR";
	}

	/* now check for home-down */
	if (!expansion)
	{
	    (void) sprintf(buf2, "\033[%d;1H", tp->Numbers[2]);
	    len = strlen(buf2);
	    if (strncmp(buf2, sp, len) == 0)
		    expansion = "LL";
	}

	/* now look at the expansion we got, if any */
	if (expansion)
	{
	    (void) sprintf(buf + strlen(buf), "{%s}", expansion);
	    sp += len - 1;
	    continue;
	}
	else
	{
	    /* couldn't match anything */
	    buf2[0] = *sp;
	    buf2[1] = '\0';
	    (void) strcat(buf, _nc_tic_expand(buf2, outform==F_TERMINFO));
	}
    }
    (void) printf("%s\n", buf);
}
Example #5
0
static void
analyze_string(const char *name, const char *cap, TERMTYPE *tp)
{
    char buf[MAX_TERMINFO_LENGTH];
    char buf2[MAX_TERMINFO_LENGTH];
    const char *sp;
    const assoc *ap;
    int tp_lines = tp->Numbers[2];

    if (cap == ABSENT_STRING || cap == CANCELLED_STRING)
	return;
    (void) printf("%s: ", name);

    buf[0] = '\0';
    for (sp = cap; *sp; sp++) {
	int i;
	int csi;
	size_t len = 0;
	size_t next;
	const char *expansion = 0;
	char buf3[MAX_TERMINFO_LENGTH];

	/* first, check other capabilities in this entry */
	for (i = 0; i < STRCOUNT; i++) {
	    char *cp = tp->Strings[i];

	    /* don't use soft-key capabilities */
	    if (strnames[i][0] == 'k' && strnames[i][0] == 'f')
		continue;

	    if (cp != ABSENT_STRING && cp != CANCELLED_STRING && cp[0] && cp
		!= cap) {
		len = strlen(cp);
		(void) strncpy(buf2, sp, len);
		buf2[len] = '\0';

		if (_nc_capcmp(cp, buf2))
		    continue;

#define ISRS(s)	(!strncmp((s), "is", 2) || !strncmp((s), "rs", 2))
		/*
		 * Theoretically we just passed the test for translation
		 * (equality once the padding is stripped).  However, there
		 * are a few more hoops that need to be jumped so that
		 * identical pairs of initialization and reset strings
		 * don't just refer to each other.
		 */
		if (ISRS(name) || ISRS(strnames[i]))
		    if (cap < cp)
			continue;
#undef ISRS

		expansion = strnames[i];
		break;
	    }
	}

	/* now check the standard capabilities */
	if (!expansion) {
	    csi = skip_csi(sp);
	    for (ap = std_caps; ap->from; ap++) {
		size_t adj = csi ? 2 : 0;

		len = strlen(ap->from);
		if (csi && skip_csi(ap->from) != csi)
		    continue;
		if (len > adj
		    && strncmp(ap->from + adj, sp + csi, len - adj) == 0) {
		    expansion = ap->to;
		    len -= adj;
		    len += csi;
		    break;
		}
	    }
	}

	/* now check for standard-mode sequences */
	if (!expansion
	    && (csi = skip_csi(sp)) != 0
	    && (len = strspn(sp + csi, "0123456789;"))
	    && (next = csi + len)
	    && ((sp[next] == 'h') || (sp[next] == 'l'))) {

	    (void) strcpy(buf2, (sp[next] == 'h') ? "ECMA+" : "ECMA-");
	    (void) strncpy(buf3, sp + csi, len);
	    buf3[len] = '\0';
	    len += csi + 1;

	    expansion = lookup_params(std_modes, buf2, buf3);
	}

	/* now check for private-mode sequences */
	if (!expansion
	    && (csi = skip_csi(sp)) != 0
	    && sp[csi] == '?'
	    && (len = strspn(sp + csi + 1, "0123456789;"))
	    && (next = csi + 1 + len)
	    && ((sp[next] == 'h') || (sp[next] == 'l'))) {

	    (void) strcpy(buf2, (sp[next] == 'h') ? "DEC+" : "DEC-");
	    (void) strncpy(buf3, sp + csi + 1, len);
	    buf3[len] = '\0';
	    len += csi + 2;

	    expansion = lookup_params(private_modes, buf2, buf3);
	}

	/* now check for ECMA highlight sequences */
	if (!expansion
	    && (csi = skip_csi(sp)) != 0
	    && (len = strspn(sp + csi, "0123456789;")) != 0
	    && (next = csi + len)
	    && sp[next] == 'm') {

	    (void) strcpy(buf2, "SGR:");
	    (void) strncpy(buf3, sp + csi, len);
	    buf3[len] = '\0';
	    len += csi + 1;

	    expansion = lookup_params(ecma_highlights, buf2, buf3);
	}

	if (!expansion
	    && (csi = skip_csi(sp)) != 0
	    && sp[csi] == 'm') {
	    len = csi + 1;
	    (void) strcpy(buf2, "SGR:");
	    strcat(buf2, ecma_highlights[0].to);
	    expansion = buf2;
	}

	/* now check for scroll region reset */
	if (!expansion
	    && (csi = skip_csi(sp)) != 0) {
	    if (sp[csi] == 'r') {
		expansion = "RSR";
		len = 1;
	    } else {
		(void) sprintf(buf2, "1;%dr", tp_lines);
		len = strlen(buf2);
		if (strncmp(buf2, sp + csi, len) == 0)
		    expansion = "RSR";
	    }
	    len += csi;
	}

	/* now check for home-down */
	if (!expansion
	    && (csi = skip_csi(sp)) != 0) {
	    (void) sprintf(buf2, "%d;1H", tp_lines);
	    len = strlen(buf2);
	    if (strncmp(buf2, sp + csi, len) == 0) {
		expansion = "LL";
	    } else {
		(void) sprintf(buf2, "%dH", tp_lines);
		len = strlen(buf2);
		if (strncmp(buf2, sp + csi, len) == 0) {
		    expansion = "LL";
		}
	    }
	    len += csi;
	}

	/* now look at the expansion we got, if any */
	if (expansion) {
	    (void) sprintf(buf + strlen(buf), "{%s}", expansion);
	    sp += len - 1;
	    continue;
	} else {
	    /* couldn't match anything */
	    buf2[0] = *sp;
	    buf2[1] = '\0';
	    (void) strcat(buf, TIC_EXPAND(buf2));
	}
    }
    (void) printf("%s\n", buf);
}