Alien-uv
view release on metacpan or search on metacpan
libuv/src/win/tty.c view on Meta::CPAN
FLUSH_TEXT();
continue;
}
for (j = 0; j < buf.len; j++) {
unsigned char c = buf.base[j];
/* Run the character through the utf8 decoder We happily accept non
* shortest form encodings and invalid code points - there's no real harm
* that can be done. */
if (utf8_bytes_left == 0) {
/* Read utf-8 start byte */
DWORD first_zero_bit;
unsigned char not_c = ~c;
#ifdef _MSC_VER /* msvc */
if (_BitScanReverse(&first_zero_bit, not_c)) {
#else /* assume gcc */
if (c != 0) {
first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c);
#endif
if (first_zero_bit == 7) {
/* Ascii - pass right through */
utf8_codepoint = (unsigned int) c;
} else if (first_zero_bit <= 5) {
/* Multibyte sequence */
utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c;
utf8_bytes_left = (char) (6 - first_zero_bit);
} else {
/* Invalid continuation */
utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
}
} else {
/* 0xff -- invalid */
utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
}
} else if ((c & 0xc0) == 0x80) {
/* Valid continuation of utf-8 multibyte sequence */
utf8_bytes_left--;
utf8_codepoint <<= 6;
utf8_codepoint |= ((unsigned int) c & 0x3f);
} else {
/* Start byte where continuation was expected. */
utf8_bytes_left = 0;
utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER;
/* Patch buf offset so this character will be parsed again as a start
* byte. */
j--;
}
/* Maybe we need to parse more bytes to find a character. */
if (utf8_bytes_left != 0) {
continue;
}
/* Parse vt100/ansi escape codes */
if (ansi_parser_state == ANSI_NORMAL) {
switch (utf8_codepoint) {
case '\033':
ansi_parser_state = ANSI_ESCAPE_SEEN;
continue;
case 0233:
ansi_parser_state = ANSI_CSI;
handle->tty.wr.ansi_csi_argc = 0;
continue;
}
} else if (ansi_parser_state == ANSI_ESCAPE_SEEN) {
switch (utf8_codepoint) {
case '[':
ansi_parser_state = ANSI_CSI;
handle->tty.wr.ansi_csi_argc = 0;
continue;
case '^':
case '_':
case 'P':
case ']':
/* Not supported, but we'll have to parse until we see a stop code,
* e. g. ESC \ or BEL. */
ansi_parser_state = ANSI_ST_CONTROL;
continue;
case '\033':
/* Ignore double escape. */
continue;
case 'c':
/* Full console reset. */
FLUSH_TEXT();
uv_tty_reset(handle, error);
ansi_parser_state = ANSI_NORMAL;
continue;
case '7':
/* Save the cursor position and text attributes. */
FLUSH_TEXT();
uv_tty_save_state(handle, 1, error);
ansi_parser_state = ANSI_NORMAL;
continue;
case '8':
/* Restore the cursor position and text attributes */
FLUSH_TEXT();
uv_tty_restore_state(handle, 1, error);
ansi_parser_state = ANSI_NORMAL;
continue;
default:
if (utf8_codepoint >= '@' && utf8_codepoint <= '_') {
/* Single-char control. */
ansi_parser_state = ANSI_NORMAL;
continue;
} else {
/* Invalid - proceed as normal, */
ansi_parser_state = ANSI_NORMAL;
}
}
} else if (ansi_parser_state & ANSI_CSI) {
if (!(ansi_parser_state & ANSI_IGNORE)) {
if (utf8_codepoint >= '0' && utf8_codepoint <= '9') {
/* Parsing a numerical argument */
if (!(ansi_parser_state & ANSI_IN_ARG)) {
/* We were not currently parsing a number */
/* Check for too many arguments */
if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE;
continue;
}
ansi_parser_state |= ANSI_IN_ARG;
handle->tty.wr.ansi_csi_argc++;
handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) utf8_codepoint - '0';
continue;
} else {
/* We were already parsing a number. Parse next digit. */
uint32_t value = 10 *
handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
/* Check for overflow. */
if (value > UINT16_MAX) {
( run in 0.898 second using v1.01-cache-2.11-cpan-e1769b4cff6 )