Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2017-01-26 21:30:06 -08:00
8 changed files with 334 additions and 78 deletions
+1 -32
View File
@@ -12530,39 +12530,8 @@ f_timer_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
static void
f_tolower(typval_T *argvars, typval_T *rettv)
{
char_u *p;
p = vim_strsave(get_tv_string(&argvars[0]));
rettv->v_type = VAR_STRING;
rettv->vval.v_string = p;
if (p != NULL)
while (*p != NUL)
{
#ifdef FEAT_MBYTE
int l;
if (enc_utf8)
{
int c, lc;
c = utf_ptr2char(p);
lc = utf_tolower(c);
l = utf_ptr2len(p);
/* TODO: reallocate string when byte count changes. */
if (utf_char2len(lc) == l)
utf_char2bytes(lc, p);
p += l;
}
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;
}
}
rettv->vval.v_string = strlow_save(get_tv_string(&argvars[0]));
}
/*
+67 -29
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
/*
@@ -1740,34 +1806,6 @@ vim_memset(void *ptr, int c, size_t size)
}
#endif
/* skipped when generating prototypes, the prototype is in vim.h */
#ifdef VIM_MEMMOVE
/*
* Version of memmove() that handles overlapping source and destination.
* For systems that don't have a function that is guaranteed to do that (SYSV).
*/
void
mch_memmove(void *src_arg, void *dst_arg, size_t len)
{
/*
* A void doesn't have a size, we use char pointers.
*/
char *dst = dst_arg, *src = src_arg;
/* overlap, copy backwards */
if (dst > src && dst < src + len)
{
src += len;
dst += len;
while (len-- > 0)
*--dst = *--src;
}
else /* copy forwards */
while (len-- > 0)
*dst++ = *src++;
}
#endif
#if (!defined(HAVE_STRCASECMP) && !defined(HAVE_STRICMP)) || defined(PROTO)
/*
* Compare two strings, ignoring case, using current locale.
+4 -8
View File
@@ -423,21 +423,17 @@ typedef struct dsc$descriptor DESC;
# endif
#endif
/* memmove is not present on all systems, use memmove, bcopy, memcpy or our
* own version */
/* Some systems have (void *) arguments, some (char *). If we use (char *) it
/* memmove() is not present on all systems, use memmove, bcopy or memcpy.
* Some systems have (void *) arguments, some (char *). If we use (char *) it
* works for all */
#ifdef USEMEMMOVE
#if defined(USEMEMMOVE) || (!defined(USEBCOPY) && !defined(USEMEMCPY))
# define mch_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
#else
# ifdef USEBCOPY
# define mch_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
# else
# ifdef USEMEMCPY
/* ifdef USEMEMCPY */
# define mch_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
# else
# define VIM_MEMMOVE /* found in misc2.c */
# endif
# endif
#endif
+1
View File
@@ -40,6 +40,7 @@ char_u *vim_strsave_up(char_u *string);
char_u *vim_strnsave_up(char_u *string, int len);
void vim_strup(char_u *p);
char_u *strup_save(char_u *orig);
char_u *strlow_save(char_u *orig);
void del_trailing_spaces(char_u *ptr);
void vim_strncpy(char_u *to, char_u *from, size_t len);
void vim_strcat(char_u *to, char_u *from, size_t tosize);
+145
View File
@@ -16,3 +16,148 @@ func Test_str2nr()
call assert_equal(123456789, str2nr('123456789'))
call assert_equal(-123456789, str2nr('-123456789'))
endfunc
func Test_tolower()
call assert_equal("", tolower(""))
" Test with all printable ASCII characters.
call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',
\ tolower(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
if !has('multi_byte')
return
endif
" Test with a few uppercase diacritics.
call assert_equal("aàáâãäåāăąǎǟǡả", tolower("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
call assert_equal("bḃḇ", tolower("BḂḆ"))
call assert_equal("cçćĉċč", tolower("CÇĆĈĊČ"))
call assert_equal("dďđḋḏḑ", tolower("DĎĐḊḎḐ"))
call assert_equal("eèéêëēĕėęěẻẽ", tolower("EÈÉÊËĒĔĖĘĚẺẼ"))
call assert_equal("fḟ ", tolower("FḞ "))
call assert_equal("gĝğġģǥǧǵḡ", tolower("GĜĞĠĢǤǦǴḠ"))
call assert_equal("hĥħḣḧḩ", tolower("HĤĦḢḦḨ"))
call assert_equal("iìíîïĩīĭįiǐỉ", tolower("IÌÍÎÏĨĪĬĮİǏỈ"))
call assert_equal("jĵ", tolower("JĴ"))
call assert_equal("kķǩḱḵ", tolower("KĶǨḰḴ"))
call assert_equal("lĺļľŀłḻ", tolower("LĹĻĽĿŁḺ"))
call assert_equal("mḿṁ", tolower("MḾṀ"))
call assert_equal("nñńņňṅṉ", tolower("NÑŃŅŇṄṈ"))
call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
call assert_equal("pṕṗ", tolower("PṔṖ"))
call assert_equal("q", tolower("Q"))
call assert_equal("rŕŗřṙṟ", tolower("RŔŖŘṘṞ"))
call assert_equal("sśŝşšṡ", tolower("SŚŜŞŠṠ"))
call assert_equal("tţťŧṫṯ", tolower("TŢŤŦṪṮ"))
call assert_equal("uùúûüũūŭůűųưǔủ", tolower("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
call assert_equal("vṽ", tolower("VṼ"))
call assert_equal("wŵẁẃẅẇ", tolower("WŴẀẂẄẆ"))
call assert_equal("xẋẍ", tolower("XẊẌ"))
call assert_equal("yýŷÿẏỳỷỹ", tolower("YÝŶŸẎỲỶỸ"))
call assert_equal("zźżžƶẑẕ", tolower("ZŹŻŽƵẐẔ"))
" Test with a few lowercase diacritics, which should remain unchanged.
call assert_equal("aàáâãäåāăąǎǟǡả", tolower("aàáâãäåāăąǎǟǡả"))
call assert_equal("bḃḇ", tolower("bḃḇ"))
call assert_equal("cçćĉċč", tolower("cçćĉċč"))
call assert_equal("dďđḋḏḑ", tolower("dďđḋḏḑ"))
call assert_equal("eèéêëēĕėęěẻẽ", tolower("eèéêëēĕėęěẻẽ"))
call assert_equal("fḟ", tolower("fḟ"))
call assert_equal("gĝğġģǥǧǵḡ", tolower("gĝğġģǥǧǵḡ"))
call assert_equal("hĥħḣḧḩẖ", tolower("hĥħḣḧḩẖ"))
call assert_equal("iìíîïĩīĭįǐỉ", tolower("iìíîïĩīĭįǐỉ"))
call assert_equal("jĵǰ", tolower("jĵǰ"))
call assert_equal("kķǩḱḵ", tolower("kķǩḱḵ"))
call assert_equal("lĺļľŀłḻ", tolower("lĺļľŀłḻ"))
call assert_equal("mḿṁ ", tolower("mḿṁ "))
call assert_equal("nñńņňʼnṅṉ", tolower("nñńņňʼnṅṉ"))
call assert_equal("oòóôõöøōŏőơǒǫǭỏ", tolower("oòóôõöøōŏőơǒǫǭỏ"))
call assert_equal("pṕṗ", tolower("pṕṗ"))
call assert_equal("q", tolower("q"))
call assert_equal("rŕŗřṙṟ", tolower("rŕŗřṙṟ"))
call assert_equal("sśŝşšṡ", tolower("sśŝşšṡ"))
call assert_equal("tţťŧṫṯẗ", tolower("tţťŧṫṯẗ"))
call assert_equal("uùúûüũūŭůűųưǔủ", tolower("uùúûüũūŭůűųưǔủ"))
call assert_equal("vṽ", tolower("vṽ"))
call assert_equal("wŵẁẃẅẇẘ", tolower("wŵẁẃẅẇẘ"))
call assert_equal("ẋẍ", tolower("ẋẍ"))
call assert_equal("yýÿŷẏẙỳỷỹ", tolower("yýÿŷẏẙỳỷỹ"))
call assert_equal("zźżžƶẑẕ", tolower("zźżžƶẑẕ"))
" According to https://twitter.com/jifa/status/625776454479970304
" Ⱥ (U+023A) and Ⱦ (U+023E) are the *only* code points to increase
" in length (2 to 3 bytes) when lowercased. So let's test them.
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
endfunc
func Test_toupper()
call assert_equal("", toupper(""))
" Test with all printable ASCII characters.
call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~',
\ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
if !has('multi_byte')
return
endif
" Test with a few lowercase diacritics.
call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("aàáâãäåāăąǎǟǡả"))
call assert_equal("BḂḆ", toupper("bḃḇ"))
call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč"))
call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ"))
call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("eèéêëēĕėęěẻẽ"))
call assert_equal("FḞ", toupper("fḟ"))
call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("gĝğġģǥǧǵḡ"))
call assert_equal("HĤĦḢḦḨẖ", toupper("hĥħḣḧḩẖ"))
call assert_equal("IÌÍÎÏĨĪĬĮǏỈ", toupper("iìíîïĩīĭįǐỉ"))
call assert_equal("JĴǰ", toupper("jĵǰ"))
call assert_equal("KĶǨḰḴ", toupper("kķǩḱḵ"))
call assert_equal("LĹĻĽĿŁḺ", toupper("lĺļľŀłḻ"))
call assert_equal("MḾṀ ", toupper("mḿṁ "))
call assert_equal("NÑŃŅŇʼnṄṈ", toupper("nñńņňʼnṅṉ"))
call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("oòóôõöøōŏőơǒǫǭỏ"))
call assert_equal("PṔṖ", toupper("pṕṗ"))
call assert_equal("Q", toupper("q"))
call assert_equal("RŔŖŘṘṞ", toupper("rŕŗřṙṟ"))
call assert_equal("SŚŜŞŠṠ", toupper("sśŝşšṡ"))
call assert_equal("TŢŤŦṪṮẗ", toupper("tţťŧṫṯẗ"))
call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("uùúûüũūŭůűųưǔủ"))
call assert_equal("VṼ", toupper("vṽ"))
call assert_equal("WŴẀẂẄẆẘ", toupper("wŵẁẃẅẇẘ"))
call assert_equal("ẊẌ", toupper("ẋẍ"))
call assert_equal("YÝŸŶẎẙỲỶỸ", toupper("yýÿŷẏẙỳỷỹ"))
call assert_equal("ZŹŻŽƵẐẔ", toupper("zźżžƶẑẕ"))
" Test that uppercase diacritics, which should remain unchanged.
call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("AÀÁÂÃÄÅĀĂĄǍǞǠẢ"))
call assert_equal("BḂḆ", toupper("BḂḆ"))
call assert_equal("CÇĆĈĊČ", toupper("CÇĆĈĊČ"))
call assert_equal("DĎĐḊḎḐ", toupper("DĎĐḊḎḐ"))
call assert_equal("EÈÉÊËĒĔĖĘĚẺẼ", toupper("EÈÉÊËĒĔĖĘĚẺẼ"))
call assert_equal("FḞ ", toupper("FḞ "))
call assert_equal("GĜĞĠĢǤǦǴḠ", toupper("GĜĞĠĢǤǦǴḠ"))
call assert_equal("HĤĦḢḦḨ", toupper("HĤĦḢḦḨ"))
call assert_equal("IÌÍÎÏĨĪĬĮİǏỈ", toupper("IÌÍÎÏĨĪĬĮİǏỈ"))
call assert_equal("JĴ", toupper("JĴ"))
call assert_equal("KĶǨḰḴ", toupper("KĶǨḰḴ"))
call assert_equal("LĹĻĽĿŁḺ", toupper("LĹĻĽĿŁḺ"))
call assert_equal("MḾṀ", toupper("MḾṀ"))
call assert_equal("NÑŃŅŇṄṈ", toupper("NÑŃŅŇṄṈ"))
call assert_equal("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ", toupper("OÒÓÔÕÖØŌŎŐƠǑǪǬỎ"))
call assert_equal("PṔṖ", toupper("PṔṖ"))
call assert_equal("Q", toupper("Q"))
call assert_equal("RŔŖŘṘṞ", toupper("RŔŖŘṘṞ"))
call assert_equal("SŚŜŞŠṠ", toupper("SŚŜŞŠṠ"))
call assert_equal("TŢŤŦṪṮ", toupper("TŢŤŦṪṮ"))
call assert_equal("UÙÚÛÜŨŪŬŮŰŲƯǓỦ", toupper("UÙÚÛÜŨŪŬŮŰŲƯǓỦ"))
call assert_equal("VṼ", toupper("VṼ"))
call assert_equal("WŴẀẂẄẆ", toupper("WŴẀẂẄẆ"))
call assert_equal("XẊẌ", toupper("XẊẌ"))
call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
endfunc
+104
View File
@@ -102,3 +102,107 @@ func Test_CmdUndefined()
call assert_fails('Dothat', 'E492:')
call assert_equal('yes', g:didnot)
endfunc
func Test_CmdErrors()
call assert_fails('com! docmd :', 'E183:')
call assert_fails('com! \<Tab> :', 'E182:')
call assert_fails('com! _ :', 'E182:')
call assert_fails('com! X :', 'E841:')
call assert_fails('com! - DoCmd :', 'E175:')
call assert_fails('com! -xxx DoCmd :', 'E181:')
call assert_fails('com! -addr DoCmd :', 'E179:')
call assert_fails('com! -complete DoCmd :', 'E179:')
call assert_fails('com! -complete=xxx DoCmd :', 'E180:')
call assert_fails('com! -complete=custom DoCmd :', 'E467:')
call assert_fails('com! -complete=customlist DoCmd :', 'E467:')
call assert_fails('com! -complete=behave,CustomComplete DoCmd :', 'E468:')
call assert_fails('com! -nargs=x DoCmd :', 'E176:')
call assert_fails('com! -count=1 -count=2 DoCmd :', 'E177:')
call assert_fails('com! -count=x DoCmd :', 'E178:')
call assert_fails('com! -range=x DoCmd :', 'E178:')
com! -nargs=0 DoCmd :
call assert_fails('DoCmd x', 'E488:')
com! -nargs=1 DoCmd :
call assert_fails('DoCmd', 'E471:')
com! -nargs=+ DoCmd :
call assert_fails('DoCmd', 'E471:')
call assert_fails('com DoCmd :', 'E174:')
comclear
call assert_fails('delcom DoCmd', 'E184:')
endfunc
func CustomComplete(A, L, P)
return "January\nFebruary\nMars\n"
endfunc
func CustomCompleteList(A, L, P)
return [ "Monday", "Tuesday", "Wednesday" ]
endfunc
func Test_CmdCompletion()
call feedkeys(":com -\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com -addr bang bar buffer complete count nargs range register', @:)
call feedkeys(":com -nargs=0 -\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com -nargs=0 -addr bang bar buffer complete count nargs range register', @:)
call feedkeys(":com -nargs=\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com -nargs=* + 0 1 ?', @:)
call feedkeys(":com -addr=\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com -addr=arguments buffers lines loaded_buffers quickfix tabs windows', @:)
call feedkeys(":com -complete=co\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com -complete=color command compiler', @:)
command! DoCmd1 :
command! DoCmd2 :
call feedkeys(":com \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com DoCmd1 DoCmd2', @:)
call feedkeys(":DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd1 DoCmd2', @:)
call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"delcom DoCmd1 DoCmd2', @:)
delcom DoCmd1
call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"delcom DoCmd2', @:)
call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com DoCmd2', @:)
delcom DoCmd2
call feedkeys(":delcom DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"delcom DoC', @:)
call feedkeys(":com DoC\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"com DoC', @:)
com! -complete=behave DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd mswin xterm', @:)
" This does not work. Why?
"call feedkeys(":DoCmd x\<C-A>\<C-B>\"\<CR>", 'tx')
"call assert_equal('"DoCmd xterm', @:)
com! -complete=custom,CustomComplete DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd January February Mars', @:)
com! -complete=customlist,CustomCompleteList DoCmd :
call feedkeys(":DoCmd \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"DoCmd Monday Tuesday Wednesday', @:)
com! -complete=custom,CustomCompleteList DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E730:')
com! -complete=customlist,CustomComp DoCmd :
call assert_fails("call feedkeys(':DoCmd \<C-D>', 'tx')", 'E117:')
endfunc
+10
View File
@@ -779,6 +779,16 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
243,
/**/
242,
/**/
241,
/**/
240,
/**/
239,
/**/
238,
/**/
+2 -9
View File
@@ -1717,15 +1717,8 @@ typedef unsigned short disptick_T; /* display tick type */
typedef void *vim_acl_T; /* dummy to pass an ACL to a function */
/*
* Include a prototype for mch_memmove(), it may not be in alloc.pro.
*/
#ifdef VIM_MEMMOVE
void mch_memmove(void *, void *, size_t);
#else
# ifndef mch_memmove
# define mch_memmove(to, from, len) memmove(to, from, len)
# endif
#ifndef mch_memmove
# define mch_memmove(to, from, len) memmove((char*)(to), (char*)(from), (char*)(len))
#endif
/*