1
0
forked from aniani/vim

patch 8.0.0243: tolower() does not work if the byte count changes

Problem:    When making a character lower case with tolower() changes the byte
            cound, it is not made lower case.
Solution:   Add strlow_save(). (Dominique Pelle, closes #1406)
This commit is contained in:
Bram Moolenaar
2017-01-26 22:51:56 +01:00
parent 65c836e600
commit cc5b22b3bf
5 changed files with 216 additions and 33 deletions

View File

@@ -1602,7 +1602,10 @@ strup_save(char_u *orig)
{
s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
if (s == NULL)
break;
{
vim_free(res);
return NULL;
}
mch_memmove(s, res, p - res);
STRCPY(s + (p - res) + newl, p + l);
p = s + (p - res);
@@ -1625,6 +1628,69 @@ strup_save(char_u *orig)
return res;
}
/*
* Make string "s" all lower-case and return it in allocated memory.
* Handles multi-byte characters as well as possible.
* Returns NULL when out of memory.
*/
char_u *
strlow_save(char_u *orig)
{
char_u *p;
char_u *res;
res = p = vim_strsave(orig);
if (res != NULL)
while (*p != NUL)
{
# ifdef FEAT_MBYTE
int l;
if (enc_utf8)
{
int c, lc;
int newl;
char_u *s;
c = utf_ptr2char(p);
lc = utf_tolower(c);
/* Reallocate string when byte count changes. This is rare,
* thus it's OK to do another malloc()/free(). */
l = utf_ptr2len(p);
newl = utf_char2len(lc);
if (newl != l)
{
s = alloc((unsigned)STRLEN(res) + 1 + newl - l);
if (s == NULL)
{
vim_free(res);
return NULL;
}
mch_memmove(s, res, p - res);
STRCPY(s + (p - res) + newl, p + l);
p = s + (p - res);
vim_free(res);
res = s;
}
utf_char2bytes(lc, p);
p += newl;
}
else if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
p += l; /* skip multi-byte character */
else
# endif
{
*p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */
p++;
}
}
return res;
}
#endif
/*