diff --git a/Changes b/Changes index 807aebf..ee79615 100644 --- a/Changes +++ b/Changes @@ -2,6 +2,8 @@ Release ... * When a multicolumn character was replaced by another multicolumn character in insert mode, the display was not updated appropriately with terminals other than xterm. +* The '\u', '\l', '\U', and '\L' substitution sequences work with multibyte + characters now. * Handle character case conversions with the '~' vi command correctly if the length of the converted multibyte sequence is smaller than the original one. * Fixed an old vi bug: If a vi command that yanked or deleted part of a line diff --git a/ex_re.c b/ex_re.c index 381ce5b..ef77424 100644 --- a/ex_re.c +++ b/ex_re.c @@ -73,7 +73,7 @@ #ifndef lint #ifdef DOSCCS -static char sccsid[] = "@(#)ex_re.c 1.43 (gritter) 1/2/05"; +static char sccsid[] = "@(#)ex_re.c 1.44 (gritter) 1/9/05"; #endif #endif @@ -576,7 +576,7 @@ void dosub(void) { register char *lp, *sp, *rp; - int c; + int c, n; #ifdef BIT8 register char *qp; int q; @@ -591,10 +591,13 @@ dosub(void) while (lp < loc1) *sp++ = *lp++; casecnt = 0; - while (c = *rp++) { + while (*rp) { + nextc(c, rp, n); + rp += n; #ifdef BIT8 c &= TRIM; - q = *qp++; + q = *qp; + qp += n; #endif /* ^V from vi to split lines */ if (c == '\r') @@ -649,17 +652,29 @@ dosub(void) goto ovflo; continue; } -#ifndef BIT8 - if (casecnt) - *sp++ = fixcase(c & TRIM); - else - *sp++ = c & TRIM; -#else - if (casecnt) - *sp++ = fixcase(c); - else - *sp++ = c; -#endif +#ifdef MB + if (mb_cur_max > 1) { + char mb[MB_CUR_MAX+1]; + int i, m; + if (casecnt) + c = fixcase(c & TRIM); + if (c & INVBIT || (m = wctomb(mb, c)) <= 0) { + *mb = rp[-n]; + m = 1; + } + for (i = 0; i < m; i++) { + *sp++ = mb[i]; + if (sp >= &genbuf[LBSIZE]) + goto ovflo; + } + } else +#endif /* MB */ + { + if (casecnt) + *sp++ = fixcase(c & TRIM); + else + *sp++ = c & TRIM; + } if (sp >= &genbuf[LBSIZE]) ovflo: error(catgets(catd, 1, 130, @@ -680,23 +695,62 @@ fixcase(register int c) if (casecnt == 0) return (c); casecnt--; - if (destuc) { - if (islower(c)) - c = toupper(c); +#ifdef MB + if (c & INVBIT) + return (c); + if (mb_cur_max > 1) { + if (destuc) { + if (iswlower(c)) + c = towupper(c); + } else + if (iswupper(c)) + c = towlower(c); } else - if (isupper(c)) - c = tolower(c); +#endif /* MB */ + { + if (destuc) { + if (islower(c)) + c = toupper(c); + } else + if (isupper(c)) + c = tolower(c); + } return (c); } char * place(register char *sp, register char *l1, register char *l2) { - while (l1 < l2) { - *sp++ = fixcase(*l1++); - if (sp >= &genbuf[LBSIZE]) - return (0); +#ifdef MB + if (mb_cur_max > 1) { + char mb[MB_LEN_MAX+1]; + int c, i, m, n; + + nextc(c, l1, m); + if (c & INVBIT) { + m = n = 1; + *mb = *l1; + } else { + c = fixcase(c); + if ((n = wctomb(mb, c)) <= 0) { + n = 1; + *mb = *l1; + } + } + l1 += m; + for (i = 0; i < n; i++) { + *sp++ = mb[i]; + if (sp >= &genbuf[LBSIZE]) + return (0); + } + } else +#endif /* MB */ + { + *sp++ = fixcase(*l1++); + if (sp >= &genbuf[LBSIZE]) + return (0); + } } return (sp); } diff --git a/ex_version.c b/ex_version.c index c19993a..796fad3 100644 --- a/ex_version.c +++ b/ex_version.c @@ -70,12 +70,12 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Sccsid @(#)ex_version.c 1.109 (gritter) 1/2/05 + * Sccsid @(#)ex_version.c 1.110 (gritter) 1/9/05 */ #include "ex.h" -static char *versionstring = "@(#)Version 4.0 (gritter) 1/2/05"; +static char *versionstring = "@(#)Version 4.0 (gritter) 1/9/05"; void printver(void)