To: vim-dev@vim.org Subject: Patch 6.2f.026 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2f.026 Problem: When typing new text at the command line, old composing characters may be displayed. Solution: Don't read composing characters from after the end of the text to be displayed. Files: src/ex_getln.c, src/mbyte.c, src/message.c, src/proto/mbyte.pro, src/screen.c *** ../vim-6.2f.025/src/ex_getln.c Mon May 26 22:15:05 2003 --- src/ex_getln.c Thu May 29 22:45:46 2003 *************** *** 1403,1408 **** --- 1403,1409 ---- if (has_mbyte) { j = (*mb_char2bytes)(c, IObuff); + IObuff[j] = NUL; /* exclude composing chars */ put_on_cmdline(IObuff, j, TRUE); } else *************** *** 2152,2162 **** return; /* out of memory */ } ! for (j = start; j < len; j += mb_l) { p = ccline.cmdbuff + j; ! u8c = utfc_ptr2char(p, &u8c_c1, &u8c_c2); ! mb_l = (*mb_ptr2len_check)(p); if (ARABIC_CHAR(u8c)) { /* Do Arabic shaping. */ --- 2153,2163 ---- return; /* out of memory */ } ! for (j = start; j < start + len; j += mb_l) { p = ccline.cmdbuff + j; ! u8c = utfc_ptr2char_len(p, &u8c_c1, &u8c_c2, start + len - j); ! mb_l = utfc_ptr2len_check_len(p, start + len - j); if (ARABIC_CHAR(u8c)) { /* Do Arabic shaping. */ *************** *** 2166,2177 **** pc = prev_c; pc1 = prev_c1; prev_c1 = u8c_c1; ! nc = utf_ptr2char(p + mb_l); } else { /* displaying from left to right */ ! pc = utfc_ptr2char(p + mb_l, &pc1, &dummy); nc = prev_c; } prev_c = u8c; --- 2167,2185 ---- pc = prev_c; pc1 = prev_c1; prev_c1 = u8c_c1; ! if (j + mb_l >= start + len) ! nc = NUL; ! else ! nc = utf_ptr2char(p + mb_l); } else { /* displaying from left to right */ ! if (j + mb_l >= start + len) ! pc = NUL; ! else ! pc = utfc_ptr2char_len(p + mb_l, &pc1, &dummy, ! start + len - j - mb_l); nc = prev_c; } prev_c = u8c; *** ../vim-6.2f.025/src/mbyte.c Mon May 26 22:15:06 2003 --- src/mbyte.c Thu May 29 22:51:54 2003 *************** *** 1324,1329 **** --- 1324,1369 ---- } /* + * Convert a UTF-8 byte string to a wide chararacter. Also get up to two + * composing characters. Use no more than p[maxlen]. + */ + int + utfc_ptr2char_len(p, p1, p2, maxlen) + char_u *p; + int *p1; /* return: first composing char or 0 */ + int *p2; /* return: second composing char or 0 */ + int maxlen; + { + int len; + int c; + int cc; + + c = utf_ptr2char(p); + len = utf_ptr2len_check_len(p, maxlen); + /* Only accept a composing char when the first char isn't illegal. */ + if ((len > 1 || *p < 0x80) + && len < maxlen + && p[len] >= 0x80 + && UTF_COMPOSINGLIKE(p, p + len)) + { + *p1 = utf_ptr2char(p + len); + len += utf_ptr2len_check_len(p + len, maxlen - len); + if (len < maxlen + && p[len] >= 0x80 + && utf_iscomposing(cc = utf_ptr2char(p + len))) + *p2 = cc; + else + *p2 = 0; + } + else + { + *p1 = 0; + *p2 = 0; + } + return c; + } + + /* * Convert the character at screen position "off" to a sequence of bytes. * Includes the composing characters. * "buf" must at least have the length MB_MAXBYTES. *************** *** 1448,1454 **** } } - # if defined(FEAT_GUI_W32) || defined(PROTO) /* * Return the number of bytes the UTF-8 encoding of the character at "p[size]" * takes. This includes following composing characters. --- 1488,1493 ---- *************** *** 1459,1464 **** --- 1498,1506 ---- int size; { int len; + #ifdef FEAT_ARABIC + int prevlen; + #endif if (*p == NUL) return 0; *************** *** 1476,1492 **** * Check for composing characters. We can handle only the first two, but * skip all of them (otherwise the cursor would get stuck). */ while (len < size) { ! if (p[len] < 0x80 || !utf_iscomposing(utf_ptr2char(p + len))) break; /* Skip over composing char */ len += utf_ptr2len_check_len(p + len, size - len); } return len; } - # endif /* * Return the number of bytes the UTF-8 encoding of character "c" takes. --- 1518,1539 ---- * Check for composing characters. We can handle only the first two, but * skip all of them (otherwise the cursor would get stuck). */ + #ifdef FEAT_ARABIC + prevlen = 0; + #endif while (len < size) { ! if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len)) break; /* Skip over composing char */ + #ifdef FEAT_ARABIC + prevlen = len; + #endif len += utf_ptr2len_check_len(p + len, size - len); } return len; } /* * Return the number of bytes the UTF-8 encoding of character "c" takes. *** ../vim-6.2f.025/src/message.c Mon May 26 22:58:41 2003 --- src/message.c Thu May 29 22:50:31 2003 *************** *** 1179,1185 **** while (--len >= 0) { #ifdef FEAT_MBYTE ! if (has_mbyte && (mb_l = (*mb_ptr2len_check)(str)) > 1) { c = (*mb_ptr2char)(str); if (vim_isprintc(c)) --- 1179,1190 ---- while (--len >= 0) { #ifdef FEAT_MBYTE ! if (enc_utf8) ! /* Don't include composing chars after the end. */ ! mb_l = utfc_ptr2len_check_len(str, len + 1); ! else if (has_mbyte) ! mb_l = (*mb_ptr2len_check)(str); ! if (has_mbyte && mb_l > 1) { c = (*mb_ptr2char)(str); if (vim_isprintc(c)) *************** *** 2000,2006 **** if (has_mbyte) { cw = (*mb_ptr2cells)(s); ! l = (*mb_ptr2len_check)(s); } else { --- 2005,2015 ---- if (has_mbyte) { cw = (*mb_ptr2cells)(s); ! if (enc_utf8 && maxlen >= 0) ! /* avoid including composing chars after the end */ ! l = utfc_ptr2len_check_len(s, (int)((str + maxlen) - s)); ! else ! l = (*mb_ptr2len_check)(s); } else { *** ../vim-6.2f.025/src/proto/mbyte.pro Mon May 26 22:15:05 2003 --- src/proto/mbyte.pro Thu May 29 22:36:12 2003 *************** *** 22,27 **** --- 22,28 ---- int arabic_maycombine __ARGS((int two)); int utf_composinglike __ARGS((char_u *p1, char_u *p2)); int utfc_ptr2char __ARGS((char_u *p, int *p1, int *p2)); + int utfc_ptr2char_len __ARGS((char_u *p, int *p1, int *p2, int maxlen)); int utfc_char2bytes __ARGS((int off, char_u *buf)); int utf_ptr2len_check __ARGS((char_u *p)); int utf_byte2len __ARGS((int b)); *** ../vim-6.2f.025/src/screen.c Mon May 26 22:15:06 2003 --- src/screen.c Thu May 29 22:55:37 2003 *************** *** 5395,5408 **** /* check if this is the first byte of a multibyte */ if (has_mbyte) { ! mbyte_blen = (*mb_ptr2len_check)(ptr); if (enc_dbcs == DBCS_JPNU && c == 0x8e) mbyte_cells = 1; else if (enc_dbcs != 0) mbyte_cells = mbyte_blen; else /* enc_utf8 */ { ! u8c = utfc_ptr2char(ptr, &u8c_c1, &u8c_c2); mbyte_cells = utf_char2cells(u8c); /* Non-BMP character: display as ? or fullwidth ?. */ if (u8c >= 0x10000) --- 5395,5416 ---- /* check if this is the first byte of a multibyte */ if (has_mbyte) { ! if (enc_utf8 && len > 0) ! mbyte_blen = utfc_ptr2len_check_len(ptr, ! (int)((text + len) - ptr)); ! else ! mbyte_blen = (*mb_ptr2len_check)(ptr); if (enc_dbcs == DBCS_JPNU && c == 0x8e) mbyte_cells = 1; else if (enc_dbcs != 0) mbyte_cells = mbyte_blen; else /* enc_utf8 */ { ! if (len >= 0) ! u8c = utfc_ptr2char_len(ptr, &u8c_c1, &u8c_c2, ! (int)((text + len) - ptr)); ! else ! u8c = utfc_ptr2char(ptr, &u8c_c1, &u8c_c2); mbyte_cells = utf_char2cells(u8c); /* Non-BMP character: display as ? or fullwidth ?. */ if (u8c >= 0x10000) *** ../vim-6.2f.025/src/version.c Thu May 29 21:06:44 2003 --- src/version.c Thu May 29 22:37:58 2003 *************** *** 632,633 **** --- 632,635 ---- { /* Add new patch number below this line */ + /**/ + 26, /**/ -- How To Keep A Healthy Level Of Insanity: 3. Every time someone asks you to do something, ask if they want fries with that. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///