Exemplo n.º 1
0
/*
 * Is a given character a "binary" character?
 */
int
binary_char(LWCHAR c)
{
	if (utf_mode)
		return (is_ubin_char(c));
	c &= 0377;
	return (!isprint((unsigned char)c) && !iscntrl((unsigned char)c));
}
Exemplo n.º 2
0
/*
 * Return the printable form of a UTF-8 character.
 */
char *
prutfchar(LWCHAR ch)
{
	static char buf[32];

	if (ch == ESC) {
		(void) strlcpy(buf, "ESC", sizeof (buf));
	} else if (ch < 128 && control_char(ch)) {
		if (!control_char(ch ^ 0100))
			(void) snprintf(buf, sizeof (buf), "^%c",
			    ((char)ch) ^ 0100);
		else
			(void) snprintf(buf, sizeof (buf), binfmt, (char)ch);
	} else if (is_ubin_char(ch)) {
		(void) snprintf(buf, sizeof (buf), utfbinfmt, ch);
	} else {
		int len;
		if (ch >= 0x80000000) {
			len = 3;
			ch = 0xFFFD;
		} else {
			len =	(ch < 0x80) ? 1
			    : (ch < 0x800) ? 2
			    : (ch < 0x10000) ? 3
			    : (ch < 0x200000) ? 4
			    : (ch < 0x4000000) ? 5
			    : 6;
		}
		buf[len] = '\0';
		if (len == 1) {
			*buf = (char)ch;
		} else {
			*buf = ((1 << len) - 1) << (8 - len);
			while (--len > 0) {
				buf[len] = (char)(0x80 | (ch & 0x3F));
				ch >>= 6;
			}
			*buf |= ch;
		}
	}
	return (buf);
}
Exemplo n.º 3
0
static int
do_append(LWCHAR ch, char *rep, off_t pos)
{
	int a;
	LWCHAR prev_ch;

	a = AT_NORMAL;

	if (ch == '\b') {
		if (bs_mode == BS_CONTROL)
			goto do_control_char;

		/*
		 * A better test is needed here so we don't
		 * backspace over part of the printed
		 * representation of a binary character.
		 */
		if (curr <= lmargin ||
		    column <= lmargin ||
		    (attr[curr - 1] & (AT_ANSI|AT_BINARY))) {
			STORE_PRCHAR('\b', pos);
		} else if (bs_mode == BS_NORMAL) {
			STORE_CHAR(ch, AT_NORMAL, NULL, pos);
		} else if (bs_mode == BS_SPECIAL) {
			overstrike = backc();
		}

		return (0);
	}

	if (overstrike > 0) {
		/*
		 * Overstrike the character at the current position
		 * in the line buffer.  This will cause either
		 * underline (if a "_" is overstruck),
		 * bold (if an identical character is overstruck),
		 * or just deletion of the character in the buffer.
		 */
		overstrike = utf_mode ? -1 : 0;
		/* To be correct, this must be a base character.  */
		prev_ch = get_wchar(linebuf + curr);
		a = attr[curr];
		if (ch == prev_ch) {
			/*
			 * Overstriking a char with itself means make it bold.
			 * But overstriking an underscore with itself is
			 * ambiguous.  It could mean make it bold, or
			 * it could mean make it underlined.
			 * Use the previous overstrike to resolve it.
			 */
			if (ch == '_') {
				if ((a & (AT_BOLD|AT_UNDERLINE)) != AT_NORMAL)
					a |= (AT_BOLD|AT_UNDERLINE);
				else if (last_overstrike != AT_NORMAL)
					a |= last_overstrike;
				else
					a |= AT_BOLD;
			} else {
				a |= AT_BOLD;
			}
		} else if (ch == '_') {
			a |= AT_UNDERLINE;
			ch = prev_ch;
			rep = linebuf + curr;
		} else if (prev_ch == '_') {
			a |= AT_UNDERLINE;
		}
		/* Else we replace prev_ch, but we keep its attributes.  */
	} else if (overstrike < 0) {
		if (is_composing_char(ch) ||
		    is_combining_char(get_wchar(linebuf + curr), ch))
			/* Continuation of the same overstrike.  */
			a = last_overstrike;
		else
			overstrike = 0;
	}

	if (ch == '\t') {
		/*
		 * Expand a tab into spaces.
		 */
		switch (bs_mode) {
		case BS_CONTROL:
			goto do_control_char;
		case BS_NORMAL:
		case BS_SPECIAL:
			STORE_TAB(a, pos);
			break;
		}
	} else if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch)) {
do_control_char:
		if (ctldisp == OPT_ON ||
		    (ctldisp == OPT_ONPLUS && IS_CSI_START(ch))) {
			/*
			 * Output as a normal character.
			 */
			STORE_CHAR(ch, AT_NORMAL, rep, pos);
		} else {
			STORE_PRCHAR((char)ch, pos);
		}
	} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch)) {
		char *s;

		s = prutfchar(ch);

		if (column + (int)strlen(s) - 1 +
		    pwidth(' ', binattr, 0) + attr_ewidth(binattr) > sc_width)
			return (1);

		for (; *s != 0; s++)
			STORE_CHAR(*s, AT_BINARY, NULL, pos);
	} else {
		STORE_CHAR(ch, a, rep, pos);
	}
	return (0);
}