vim-patch:8.1.0793: incorrect error messages for functions that take a Blob

Problem:    Incorrect error messages for functions that now take a Blob
            argument.
Solution:   Adjust the error messages. (Dominique Pelle, closes vim/vim#3846)
0d17f0d1c0
This commit is contained in:
Sean Dewar
2020-12-02 18:37:18 +00:00
parent 6a02ccc222
commit c57132ec2a
7 changed files with 41 additions and 23 deletions

View File

@@ -14,7 +14,7 @@ Using expressions is introduced in chapter 41 of the user manual |usr_41.txt|.
1. Variables *variables* 1. Variables *variables*
1.1 Variable types ~ 1.1 Variable types ~
*E712* *E712* *E896* *E897* *E898*
There are seven types of variables: There are seven types of variables:
*Number* *Integer* *Number* *Integer*
@@ -610,6 +610,9 @@ Blob creation ~
A Blob can be created with a |blob-literal|: > A Blob can be created with a |blob-literal|: >
:let b = 0zFF00ED015DAF :let b = 0zFF00ED015DAF
Dots can be inserted between bytes (pair of hex characters) for readability,
they don't change the value: >
:let b = 0zFF00.ED01.5DAF
A blob can be read from a file with |readfile()| passing the {type} argument A blob can be read from a file with |readfile()| passing the {type} argument
set to "B", for example: > set to "B", for example: >
@@ -3805,8 +3808,8 @@ escape({string}, {chars}) *escape()*
*eval()* *eval()*
eval({string}) Evaluate {string} and return the result. Especially useful to eval({string}) Evaluate {string} and return the result. Especially useful to
turn the result of |string()| back into the original value. turn the result of |string()| back into the original value.
This works for Numbers, Floats, Strings and composites of This works for Numbers, Floats, Strings, Blobs and composites
them. Also works for |Funcref|s that refer to existing of them. Also works for |Funcref|s that refer to existing
functions. functions.
Can also be used as a |method|: > Can also be used as a |method|: >
@@ -5957,8 +5960,13 @@ items({dict}) *items()*
Return a |List| with all the key-value pairs of {dict}. Each Return a |List| with all the key-value pairs of {dict}. Each
|List| item is a list with two items: the key of a {dict} |List| item is a list with two items: the key of a {dict}
entry and the value of this entry. The |List| is in arbitrary entry and the value of this entry. The |List| is in arbitrary
order. order. Also see |keys()| and |values()|.
Can also be used as a |method|: > Example: >
for [key, value] in items(mydict)
echo key . ': ' . value
endfor
< Can also be used as a |method|: >
mydict->items() mydict->items()
isnan({expr}) *isnan()* isnan({expr}) *isnan()*
@@ -6129,7 +6137,8 @@ json_encode({expr}) *json_encode()*
keys({dict}) *keys()* keys({dict}) *keys()*
Return a |List| with all the keys of {dict}. The |List| is in Return a |List| with all the keys of {dict}. The |List| is in
arbitrary order. arbitrary order. Also see |items()| and |values()|.
Can also be used as a |method|: > Can also be used as a |method|: >
mydict->keys() mydict->keys()
@@ -8970,14 +8979,15 @@ stridx({haystack}, {needle} [, {start}]) *stridx()*
*string()* *string()*
string({expr}) Return {expr} converted to a String. If {expr} is a Number, string({expr}) Return {expr} converted to a String. If {expr} is a Number,
Float, String or a composition of them, then the result can be Float, String, Blob or a composition of them, then the result
parsed back with |eval()|. can be parsed back with |eval()|.
{expr} type result ~ {expr} type result ~
String 'string' String 'string'
Number 123 Number 123
Float 123.123456 or 1.123456e8 or Float 123.123456 or 1.123456e8 or
`str2float('inf')` `str2float('inf')`
Funcref `function('name')` Funcref `function('name')`
Blob 0z00112233.44556677.8899
List [item, item] List [item, item]
Dictionary {key: value, key: value} Dictionary {key: value, key: value}
Note that in String values the ' character is doubled. Note that in String values the ' character is doubled.
@@ -9735,7 +9745,7 @@ uniq({list} [, {func} [, {dict}]]) *uniq()* *E882*
values({dict}) *values()* values({dict}) *values()*
Return a |List| with all the values of {dict}. The |List| is Return a |List| with all the values of {dict}. The |List| is
in arbitrary order. in arbitrary order. Also see |items()| and |keys()|.
Can also be used as a |method|: > Can also be used as a |method|: >
mydict->values() mydict->values()

View File

@@ -96,6 +96,7 @@ PRAGMA_DIAG_POP
static char *e_listarg = N_("E686: Argument of %s must be a List"); static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listblobarg = N_("E898: Argument of %s must be a List or Blob");
static char *e_invalwindow = N_("E957: Invalid window number"); static char *e_invalwindow = N_("E957: Invalid window number");
/// Dummy va_list for passing to vim_snprintf /// Dummy va_list for passing to vim_snprintf
@@ -334,7 +335,7 @@ static void f_add(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
} else { } else {
EMSG(_(e_listreq)); EMSG(_(e_listblobreq));
} }
} }
@@ -2884,7 +2885,7 @@ static void f_get(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
} else { } else {
EMSG2(_(e_listdictarg), "get()"); EMSG2(_(e_listdictblobarg), "get()");
} }
if (tv == NULL) { if (tv == NULL) {
@@ -4853,7 +4854,7 @@ static void f_index(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
return; return;
} else if (argvars[0].v_type != VAR_LIST) { } else if (argvars[0].v_type != VAR_LIST) {
EMSG(_(e_listreq)); EMSG(_(e_listblobreq));
return; return;
} }
list_T *const l = argvars[0].vval.v_list; list_T *const l = argvars[0].vval.v_list;
@@ -5013,7 +5014,7 @@ static void f_insert(typval_T *argvars, typval_T *rettv, FunPtr fptr)
tv_copy(&argvars[0], rettv); tv_copy(&argvars[0], rettv);
} else if (argvars[0].v_type != VAR_LIST) { } else if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "insert()"); EMSG2(_(e_listblobarg), "insert()");
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
N_("insert() argument"), TV_TRANSLATE)) { N_("insert() argument"), TV_TRANSLATE)) {
long before = 0; long before = 0;
@@ -7349,7 +7350,7 @@ static void f_remove(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
} }
} else if (argvars[0].v_type != VAR_LIST) { } else if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listdictarg), "remove()"); EMSG2(_(e_listdictblobarg), "remove()");
} else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)), } else if (!var_check_lock(tv_list_locked((l = argvars[0].vval.v_list)),
arg_errmsg, TV_TRANSLATE)) { arg_errmsg, TV_TRANSLATE)) {
bool error = false; bool error = false;
@@ -7634,7 +7635,7 @@ static void f_reverse(typval_T *argvars, typval_T *rettv, FunPtr fptr)
} }
tv_blob_set_ret(rettv, b); tv_blob_set_ret(rettv, b);
} else if (argvars[0].v_type != VAR_LIST) { } else if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "reverse()"); EMSG2(_(e_listblobarg), "reverse()");
} else { } else {
list_T *const l = argvars[0].vval.v_list; list_T *const l = argvars[0].vval.v_list;
if (!var_check_lock(tv_list_locked(l), N_("reverse() argument"), if (!var_check_lock(tv_list_locked(l), N_("reverse() argument"),

View File

@@ -946,8 +946,11 @@ EXTERN char_u e_toomanyarg[] INIT(= N_(
EXTERN char_u e_dictkey[] INIT(= N_( EXTERN char_u e_dictkey[] INIT(= N_(
"E716: Key not present in Dictionary: \"%s\"")); "E716: Key not present in Dictionary: \"%s\""));
EXTERN char_u e_listreq[] INIT(= N_("E714: List required")); EXTERN char_u e_listreq[] INIT(= N_("E714: List required"));
EXTERN char_u e_listblobreq[] INIT(= N_("E897: List or Blob required"));
EXTERN char_u e_listdictarg[] INIT(= N_( EXTERN char_u e_listdictarg[] INIT(= N_(
"E712: Argument of %s must be a List or Dictionary")); "E712: Argument of %s must be a List or Dictionary"));
EXTERN char_u e_listdictblobarg[] INIT(= N_(
"E896: Argument of %s must be a List, Dictionary or Blob"));
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile")); EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading errorfile"));
EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox")); EXTERN char_u e_sandbox[] INIT(= N_("E48: Not allowed in sandbox"));
EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here")); EXTERN char_u e_secure[] INIT(= N_("E523: Not allowed here"));

View File

@@ -32,6 +32,7 @@ func Test_blob_create()
call assert_fails('let b = 0z1.1') call assert_fails('let b = 0z1.1')
call assert_fails('let b = 0z.') call assert_fails('let b = 0z.')
call assert_fails('let b = 0z001122.') call assert_fails('let b = 0z001122.')
call assert_fails('call get("", 1)', 'E896:')
endfunc endfunc
" assignment to a blob " assignment to a blob
@@ -182,6 +183,7 @@ func Test_blob_add()
call assert_equal(0z00112233, b) call assert_equal(0z00112233, b)
call assert_fails('call add(b, [9])', 'E745:') call assert_fails('call add(b, [9])', 'E745:')
call assert_fails('call add("", 0x01)', 'E897:')
endfunc endfunc
func Test_blob_empty() func Test_blob_empty()
@@ -219,7 +221,7 @@ func Test_blob_func_remove()
call assert_fails("call remove(b, 5)", 'E979:') call assert_fails("call remove(b, 5)", 'E979:')
call assert_fails("call remove(b, 1, 5)", 'E979:') call assert_fails("call remove(b, 1, 5)", 'E979:')
call assert_fails("call remove(b, 3, 2)", 'E979:') call assert_fails("call remove(b, 3, 2)", 'E979:')
call assert_fails("call remove(1, 0)", 'E712:') call assert_fails("call remove(1, 0)", 'E896:')
call assert_fails("call remove(b, b)", 'E974:') call assert_fails("call remove(b, b)", 'E974:')
endfunc endfunc
@@ -255,7 +257,7 @@ func Test_blob_index()
call assert_equal(2, index(0z11111111, 0x11, -2)) call assert_equal(2, index(0z11111111, 0x11, -2))
call assert_equal(3, index(0z11110111, 0x11, -2)) call assert_equal(3, index(0z11110111, 0x11, -2))
call assert_fails('call index("asdf", 0)', 'E714:') call assert_fails('call index("asdf", 0)', 'E897:')
endfunc endfunc
func Test_blob_insert() func Test_blob_insert()

View File

@@ -139,7 +139,7 @@ func Test_list_func_remove()
call assert_fails("call remove(l, 5)", 'E684:') call assert_fails("call remove(l, 5)", 'E684:')
call assert_fails("call remove(l, 1, 5)", 'E684:') call assert_fails("call remove(l, 1, 5)", 'E684:')
call assert_fails("call remove(l, 3, 2)", 'E16:') call assert_fails("call remove(l, 3, 2)", 'E16:')
call assert_fails("call remove(1, 0)", 'E712:') call assert_fails("call remove(1, 0)", 'E896:')
call assert_fails("call remove(l, l)", 'E745:') call assert_fails("call remove(l, l)", 'E745:')
endfunc endfunc
@@ -616,6 +616,8 @@ func Test_reverse_sort_uniq()
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1)) call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 1))
call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i')) call assert_equal(['bar', 'BAR', 'Bar', 'Foo', 'FOO', 'foo', 'FOOBAR', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l), 'i'))
call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l))) call assert_equal(['BAR', 'Bar', 'FOO', 'FOOBAR', 'Foo', 'bar', 'foo', -1, 0, 0, 0.22, 1.0e-15, 12, 18, 22, 255, 7, 9, [], {}], sort(copy(l)))
call assert_fails('call reverse("")', 'E898:')
endfunc endfunc
" splitting a string to a List " splitting a string to a List

View File

@@ -322,16 +322,16 @@ describe('execute()', function()
eq('Vim(call):E731: using Dictionary as a String', ret) eq('Vim(call):E731: using Dictionary as a String', ret)
ret = exc_exec('call execute("echo add(1, 1)", "")') ret = exc_exec('call execute("echo add(1, 1)", "")')
eq('Vim(echo):E714: List required', ret) eq('Vim(echo):E897: List or Blob required', ret)
ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "")') ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "")')
eq('Vim(echo):E714: List required', ret) eq('Vim(echo):E897: List or Blob required', ret)
ret = exc_exec('call execute("echo add(1, 1)", "silent")') ret = exc_exec('call execute("echo add(1, 1)", "silent")')
eq('Vim(echo):E714: List required', ret) eq('Vim(echo):E897: List or Blob required', ret)
ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "silent")') ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "silent")')
eq('Vim(echo):E714: List required', ret) eq('Vim(echo):E897: List or Blob required', ret)
end) end)
end) end)
end) end)

View File

@@ -739,7 +739,7 @@ describe('lua stdlib', function()
eq({NIL, NIL}, exec_lua([[return vim.fn.Nilly()]])) eq({NIL, NIL}, exec_lua([[return vim.fn.Nilly()]]))
-- error handling -- error handling
eq({false, 'Vim:E714: List required'}, exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]])) eq({false, 'Vim:E897: List or Blob required'}, exec_lua([[return {pcall(vim.fn.add, "aa", "bb")}]]))
end) end)
it('vim.fn should error when calling API function', function() it('vim.fn should error when calling API function', function()