/// Convert non-printable character to two or more printable characters in /// "buf[]". "buf" needs to be able to hold five bytes. /// Does NOT work for multi-byte characters, c must be <= 255. /// /// @param buf /// @param c void transchar_nonprint(char_u *buf, int c) { if (c == NL) { // we use newline in place of a NUL c = NUL; } else if ((c == CAR) && (get_fileformat(curbuf) == EOL_MAC)) { // we use CR in place of NL in this case c = NL; } if (dy_flags & DY_UHEX) { // 'display' has "uhex" transchar_hex(buf, c); } else if (c <= 0x7f) { // 0x00 - 0x1f and 0x7f buf[0] = '^'; // DEL displayed as ^? buf[1] = c ^ 0x40; buf[2] = NUL; } else if (enc_utf8 && (c >= 0x80)) { transchar_hex(buf, c); } else if ((c >= ' ' + 0x80) && (c <= '~' + 0x80)) { // 0xa0 - 0xfe buf[0] = '|'; buf[1] = c - 0x80; buf[2] = NUL; } else { // 0x80 - 0x9f and 0xff buf[0] = '~'; buf[1] = (c - 0x80) ^ 0x40; buf[2] = NUL; } }
/* * Convert non-printable character to two or more printable characters in * "buf[]". "buf" needs to be able to hold five bytes. * Does NOT work for multi-byte characters, c must be <= 255. */ void transchar_nonprint(char_u *buf, int c) { if (c == NL) c = NUL; /* we use newline in place of a NUL */ else if (c == CAR && get_fileformat(curbuf) == EOL_MAC) c = NL; /* we use CR in place of NL in this case */ if (dy_flags & DY_UHEX) /* 'display' has "uhex" */ transchar_hex(buf, c); else if (c <= 0x7f) { /* 0x00 - 0x1f and 0x7f */ buf[0] = '^'; buf[1] = c ^ 0x40; /* DEL displayed as ^? */ buf[2] = NUL; } else if (enc_utf8 && c >= 0x80) { transchar_hex(buf, c); } else if (c >= ' ' + 0x80 && c <= '~' + 0x80) { /* 0xa0 - 0xfe */ buf[0] = '|'; buf[1] = c - 0x80; buf[2] = NUL; } else { /* 0x80 - 0x9f and 0xff */ /* * TODO: EBCDIC I don't know what to do with this chars, so I display * them as '~?' for now */ buf[0] = '~'; buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */ buf[2] = NUL; } }
/* * Translate a string into allocated memory, replacing special chars with * printable chars. Returns NULL when out of memory. */ char_u *transstr(char_u *s) { char_u *res; char_u *p; int l, len, c; char_u hexbuf[11]; if (has_mbyte) { /* Compute the length of the result, taking account of unprintable * multi-byte characters. */ len = 0; p = s; while (*p != NUL) { if ((l = (*mb_ptr2len)(p)) > 1) { c = (*mb_ptr2char)(p); p += l; if (vim_isprintc(c)) len += l; else { transchar_hex(hexbuf, c); len += (int)STRLEN(hexbuf); } } else { l = byte2cells(*p++); if (l > 0) len += l; else len += 4; /* illegal byte sequence */ } } res = alloc((unsigned)(len + 1)); } else res = alloc((unsigned)(vim_strsize(s) + 1)); if (res != NULL) { *res = NUL; p = s; while (*p != NUL) { if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1) { c = (*mb_ptr2char)(p); if (vim_isprintc(c)) STRNCAT(res, p, l); /* append printable multi-byte char */ else transchar_hex(res + STRLEN(res), c); p += l; } else STRCAT(res, transchar_byte(*p++)); } } return res; }
/// Convert non-printable characters to 2..4 printable ones /// /// @warning Does not work for multi-byte characters, c must be <= 255. /// /// @param[out] buf Buffer to store result in, must be able to hold at least /// 5 bytes (conversion result + NUL). /// @param[in] c Character to convert. NUL is assumed to be NL according to /// `:h NL-used-for-NUL`. void transchar_nonprint(char_u *buf, int c) { if (c == NL) { // we use newline in place of a NUL c = NUL; } else if ((c == CAR) && (get_fileformat(curbuf) == EOL_MAC)) { // we use CR in place of NL in this case c = NL; } assert(c <= 0xff); if (dy_flags & DY_UHEX || c > 0x7f) { // 'display' has "uhex" transchar_hex((char *)buf, c); } else { // 0x00 - 0x1f and 0x7f buf[0] = '^'; // DEL displayed as ^? buf[1] = (char_u)(c ^ 0x40); buf[2] = NUL; } }
/// Translate a character into a printable one, leaving printable ASCII intact /// /// All unicode characters are considered non-printable in this function. /// /// @param[in] c Character to translate. /// /// @return translated character into a static buffer. char_u *transchar(int c) { int i = 0; if (IS_SPECIAL(c)) { // special key code, display as ~@ char transchar_buf[0] = '~'; transchar_buf[1] = '@'; i = 2; c = K_SECOND(c); } if ((!chartab_initialized && (((c >= ' ') && (c <= '~')) || (p_altkeymap && F_ischar(c)))) || ((c <= 0xFF) && vim_isprintc_strict(c))) { // printable character transchar_buf[i] = (char_u)c; transchar_buf[i + 1] = NUL; } else if (c <= 0xFF) { transchar_nonprint(transchar_buf + i, c); } else { transchar_hex((char *)transchar_buf + i, c); } return transchar_buf; }
/// Translate a string into allocated memory, replacing special chars with /// printable chars. Returns NULL when out of memory. /// /// @param s /// /// @return translated string char_u *transstr(char_u *s) { char_u *res; char_u *p; int l, c; char_u hexbuf[11]; if (has_mbyte) { // Compute the length of the result, taking account of unprintable // multi-byte characters. size_t len = 0; p = s; while (*p != NUL) { if ((l = (*mb_ptr2len)(p)) > 1) { c = (*mb_ptr2char)(p); p += l; if (vim_isprintc(c)) { len += l; } else { transchar_hex(hexbuf, c); len += STRLEN(hexbuf); } } else { l = byte2cells(*p++); if (l > 0) { len += l; } else { // illegal byte sequence len += 4; } } } res = xmallocz(len); } else { res = xmallocz(vim_strsize(s)); } *res = NUL; p = s; while (*p != NUL) { if (has_mbyte && ((l = (*mb_ptr2len)(p)) > 1)) { c = (*mb_ptr2char)(p); if (vim_isprintc(c)) { // append printable multi-byte char STRNCAT(res, p, l); } else { transchar_hex(res + STRLEN(res), c); } p += l; } else { STRCAT(res, transchar_byte(*p++)); } } return res; }
/* * Convert non-printable character to two or more printable characters in * "buf[]". "buf" needs to be able to hold five bytes. * Does NOT work for multi-byte characters, c must be <= 255. */ void transchar_nonprint(char_u *buf, int c) { if (c == NL) c = NUL; /* we use newline in place of a NUL */ else if (c == CAR && get_fileformat(curbuf) == EOL_MAC) c = NL; /* we use CR in place of NL in this case */ if (dy_flags & DY_UHEX) /* 'display' has "uhex" */ transchar_hex(buf, c); #ifdef EBCDIC /* For EBCDIC only the characters 0-63 and 255 are not printable */ else if (CtrlChar(c) != 0 || c == DEL) #else else if (c <= 0x7f) /* 0x00 - 0x1f and 0x7f */ #endif { buf[0] = '^'; #ifdef EBCDIC if (c == DEL) buf[1] = '?'; /* DEL displayed as ^? */ else buf[1] = CtrlChar(c); #else buf[1] = c ^ 0x40; /* DEL displayed as ^? */ #endif buf[2] = NUL; } #ifdef FEAT_MBYTE else if (enc_utf8 && c >= 0x80) { transchar_hex(buf, c); } #endif #ifndef EBCDIC else if (c >= ' ' + 0x80 && c <= '~' + 0x80) /* 0xa0 - 0xfe */ { buf[0] = '|'; buf[1] = c - 0x80; buf[2] = NUL; } #else else if (c < 64) { buf[0] = '~'; buf[1] = MetaChar(c); buf[2] = NUL; } #endif else /* 0x80 - 0x9f and 0xff */ { /* * TODO: EBCDIC I don't know what to do with this chars, so I display * them as '~?' for now */ buf[0] = '~'; #ifdef EBCDIC buf[1] = '?'; /* 0xff displayed as ~? */ #else buf[1] = (c - 0x80) ^ 0x40; /* 0xff displayed as ~? */ #endif buf[2] = NUL; } }