To: vim_dev@googlegroups.com Subject: Patch 8.2.1876 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1876 Problem: Vim9: argument types for builtin functions are not checked at compile time. Solution: Add an argument type checking mechanism. Implement type checks for one function. Files: src/evalfunc.c, src/proto/evalfunc.pro, src/vim9compile.c, src/testdir/test_vim9_func.vim, src/testdir/test_vim9_builtin.vim, src/testdir/Make_all.mak *** ../vim-8.2.1875/src/evalfunc.c 2020-10-17 19:29:47.526935795 +0200 --- src/evalfunc.c 2020-10-21 14:23:33.110211557 +0200 *************** *** 259,264 **** --- 259,297 ---- static void f_xor(typval_T *argvars, typval_T *rettv); + /* + * Functions that check the argument type of a builtin function. + * Each function returns FAIL and gives an error message if the type is wrong. + */ + + // Context passed to an arg_ function. + typedef struct { + int arg_count; // actual argument count + int arg_idx; // current argument index (first arg is zero) + } argcontext_T; + + // A function to check one argument type. The first argument is the type to + // check. If needed, other argument types can be obtained with the context. + // E.g. if "arg_idx" is 1, then (type - 1) is the first argument type. + typedef int (*argcheck_T)(type_T *, argcontext_T *); + + static int + arg_float_or_nr(type_T *type, argcontext_T *context) + { + if (type->tt_type == VAR_FLOAT || type->tt_type == VAR_NUMBER) + return OK; + arg_type_mismatch(&t_number, type, context->arg_idx + 1); + return FAIL; + } + + /* + * Lists of functions that check the argument types of a builtin function. + */ + argcheck_T arg1_float_or_nr[] = {arg_float_or_nr}; + + /* + * Functions that return the return type of a builtin function. + */ static type_T * ret_void(int argcount UNUSED, type_T **argtypes UNUSED) { *************** *** 432,437 **** --- 465,471 ---- char f_min_argc; // minimal number of arguments char f_max_argc; // maximal number of arguments char f_argtype; // for method: FEARG_ values + argcheck_T *f_argcheck; // list of functions to check argument types type_T *(*f_retfunc)(int argcount, type_T **argtypes); // return type function void (*f_func)(typval_T *args, typval_T *rvar); *************** *** 488,1108 **** static funcentry_T global_functions[] = { ! {"abs", 1, 1, FEARG_1, ret_any, FLOAT_FUNC(f_abs)}, ! {"acos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_acos)}, ! {"add", 2, 2, FEARG_1, ret_first_arg, f_add}, ! {"and", 2, 2, FEARG_1, ret_number, f_and}, ! {"append", 2, 2, FEARG_2, ret_number, f_append}, ! {"appendbufline", 3, 3, FEARG_3, ret_number, f_appendbufline}, ! {"argc", 0, 1, 0, ret_number, f_argc}, ! {"argidx", 0, 0, 0, ret_number, f_argidx}, ! {"arglistid", 0, 2, 0, ret_number, f_arglistid}, ! {"argv", 0, 2, 0, ret_argv, f_argv}, ! {"asin", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_asin)}, ! {"assert_beeps", 1, 2, FEARG_1, ret_number, f_assert_beeps}, ! {"assert_equal", 2, 3, FEARG_2, ret_number, f_assert_equal}, ! {"assert_equalfile", 2, 3, FEARG_1, ret_number, f_assert_equalfile}, ! {"assert_exception", 1, 2, 0, ret_number, f_assert_exception}, ! {"assert_fails", 1, 5, FEARG_1, ret_number, f_assert_fails}, ! {"assert_false", 1, 2, FEARG_1, ret_number, f_assert_false}, ! {"assert_inrange", 3, 4, FEARG_3, ret_number, f_assert_inrange}, ! {"assert_match", 2, 3, FEARG_2, ret_number, f_assert_match}, ! {"assert_notequal", 2, 3, FEARG_2, ret_number, f_assert_notequal}, ! {"assert_notmatch", 2, 3, FEARG_2, ret_number, f_assert_notmatch}, ! {"assert_report", 1, 1, FEARG_1, ret_number, f_assert_report}, ! {"assert_true", 1, 2, FEARG_1, ret_number, f_assert_true}, ! {"atan", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_atan)}, ! {"atan2", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_atan2)}, ! {"balloon_gettext", 0, 0, 0, ret_string, #ifdef FEAT_BEVAL f_balloon_gettext #else NULL #endif }, ! {"balloon_show", 1, 1, FEARG_1, ret_void, #ifdef FEAT_BEVAL f_balloon_show #else NULL #endif }, ! {"balloon_split", 1, 1, FEARG_1, ret_list_string, #if defined(FEAT_BEVAL_TERM) f_balloon_split #else NULL #endif }, ! {"browse", 4, 4, 0, ret_string, f_browse}, ! {"browsedir", 2, 2, 0, ret_string, f_browsedir}, ! {"bufadd", 1, 1, FEARG_1, ret_number, f_bufadd}, ! {"bufexists", 1, 1, FEARG_1, ret_number, f_bufexists}, ! {"buffer_exists", 1, 1, FEARG_1, ret_number, f_bufexists}, // obsolete ! {"buffer_name", 0, 1, FEARG_1, ret_string, f_bufname}, // obsolete ! {"buffer_number", 0, 1, FEARG_1, ret_number, f_bufnr}, // obsolete ! {"buflisted", 1, 1, FEARG_1, ret_number, f_buflisted}, ! {"bufload", 1, 1, FEARG_1, ret_void, f_bufload}, ! {"bufloaded", 1, 1, FEARG_1, ret_number, f_bufloaded}, ! {"bufname", 0, 1, FEARG_1, ret_string, f_bufname}, ! {"bufnr", 0, 2, FEARG_1, ret_number, f_bufnr}, ! {"bufwinid", 1, 1, FEARG_1, ret_number, f_bufwinid}, ! {"bufwinnr", 1, 1, FEARG_1, ret_number, f_bufwinnr}, ! {"byte2line", 1, 1, FEARG_1, ret_number, f_byte2line}, ! {"byteidx", 2, 2, FEARG_1, ret_number, f_byteidx}, ! {"byteidxcomp", 2, 2, FEARG_1, ret_number, f_byteidxcomp}, ! {"call", 2, 3, FEARG_1, ret_any, f_call}, ! {"ceil", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_ceil)}, ! {"ch_canread", 1, 1, FEARG_1, ret_number, JOB_FUNC(f_ch_canread)}, ! {"ch_close", 1, 1, FEARG_1, ret_void, JOB_FUNC(f_ch_close)}, ! {"ch_close_in", 1, 1, FEARG_1, ret_void, JOB_FUNC(f_ch_close_in)}, ! {"ch_evalexpr", 2, 3, FEARG_1, ret_any, JOB_FUNC(f_ch_evalexpr)}, ! {"ch_evalraw", 2, 3, FEARG_1, ret_any, JOB_FUNC(f_ch_evalraw)}, ! {"ch_getbufnr", 2, 2, FEARG_1, ret_number, JOB_FUNC(f_ch_getbufnr)}, ! {"ch_getjob", 1, 1, FEARG_1, ret_job, JOB_FUNC(f_ch_getjob)}, ! {"ch_info", 1, 1, FEARG_1, ret_dict_any, JOB_FUNC(f_ch_info)}, ! {"ch_log", 1, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_log)}, ! {"ch_logfile", 1, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_logfile)}, ! {"ch_open", 1, 2, FEARG_1, ret_channel, JOB_FUNC(f_ch_open)}, ! {"ch_read", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_read)}, ! {"ch_readblob", 1, 2, FEARG_1, ret_blob, JOB_FUNC(f_ch_readblob)}, ! {"ch_readraw", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_readraw)}, ! {"ch_sendexpr", 2, 3, FEARG_1, ret_void, JOB_FUNC(f_ch_sendexpr)}, ! {"ch_sendraw", 2, 3, FEARG_1, ret_void, JOB_FUNC(f_ch_sendraw)}, ! {"ch_setoptions", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_setoptions)}, ! {"ch_status", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_status)}, ! {"changenr", 0, 0, 0, ret_number, f_changenr}, ! {"char2nr", 1, 2, FEARG_1, ret_number, f_char2nr}, ! {"charclass", 1, 1, FEARG_1, ret_number, f_charclass}, ! {"chdir", 1, 1, FEARG_1, ret_string, f_chdir}, ! {"cindent", 1, 1, FEARG_1, ret_number, f_cindent}, ! {"clearmatches", 0, 1, FEARG_1, ret_void, f_clearmatches}, ! {"col", 1, 1, FEARG_1, ret_number, f_col}, ! {"complete", 2, 2, FEARG_2, ret_void, f_complete}, ! {"complete_add", 1, 1, FEARG_1, ret_number, f_complete_add}, ! {"complete_check", 0, 0, 0, ret_number, f_complete_check}, ! {"complete_info", 0, 1, FEARG_1, ret_dict_any, f_complete_info}, ! {"confirm", 1, 4, FEARG_1, ret_number, f_confirm}, ! {"copy", 1, 1, FEARG_1, ret_first_arg, f_copy}, ! {"cos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cos)}, ! {"cosh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cosh)}, ! {"count", 2, 4, FEARG_1, ret_number, f_count}, ! {"cscope_connection",0,3, 0, ret_number, f_cscope_connection}, ! {"cursor", 1, 3, FEARG_1, ret_number, f_cursor}, ! {"debugbreak", 1, 1, FEARG_1, ret_number, #ifdef MSWIN f_debugbreak #else NULL #endif }, ! {"deepcopy", 1, 2, FEARG_1, ret_first_arg, f_deepcopy}, ! {"delete", 1, 2, FEARG_1, ret_number, f_delete}, ! {"deletebufline", 2, 3, FEARG_1, ret_number, f_deletebufline}, ! {"did_filetype", 0, 0, 0, ret_number, f_did_filetype}, ! {"diff_filler", 1, 1, FEARG_1, ret_number, f_diff_filler}, ! {"diff_hlID", 2, 2, FEARG_1, ret_number, f_diff_hlID}, ! {"echoraw", 1, 1, FEARG_1, ret_number, f_echoraw}, ! {"empty", 1, 1, FEARG_1, ret_number, f_empty}, ! {"environ", 0, 0, 0, ret_dict_string, f_environ}, ! {"escape", 2, 2, FEARG_1, ret_string, f_escape}, ! {"eval", 1, 1, FEARG_1, ret_any, f_eval}, ! {"eventhandler", 0, 0, 0, ret_number, f_eventhandler}, ! {"executable", 1, 1, FEARG_1, ret_number, f_executable}, ! {"execute", 1, 2, FEARG_1, ret_string, f_execute}, ! {"exepath", 1, 1, FEARG_1, ret_string, f_exepath}, ! {"exists", 1, 1, FEARG_1, ret_number, f_exists}, ! {"exp", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_exp)}, ! {"expand", 1, 3, FEARG_1, ret_any, f_expand}, ! {"expandcmd", 1, 1, FEARG_1, ret_string, f_expandcmd}, ! {"extend", 2, 3, FEARG_1, ret_first_arg, f_extend}, ! {"feedkeys", 1, 2, FEARG_1, ret_void, f_feedkeys}, ! {"file_readable", 1, 1, FEARG_1, ret_number, f_filereadable}, // obsolete ! {"filereadable", 1, 1, FEARG_1, ret_number, f_filereadable}, ! {"filewritable", 1, 1, FEARG_1, ret_number, f_filewritable}, ! {"filter", 2, 2, FEARG_1, ret_first_arg, f_filter}, ! {"finddir", 1, 3, FEARG_1, ret_string, f_finddir}, ! {"findfile", 1, 3, FEARG_1, ret_string, f_findfile}, ! {"flatten", 1, 2, FEARG_1, ret_list_any, f_flatten}, ! {"float2nr", 1, 1, FEARG_1, ret_number, FLOAT_FUNC(f_float2nr)}, ! {"floor", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_floor)}, ! {"fmod", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_fmod)}, ! {"fnameescape", 1, 1, FEARG_1, ret_string, f_fnameescape}, ! {"fnamemodify", 2, 2, FEARG_1, ret_string, f_fnamemodify}, ! {"foldclosed", 1, 1, FEARG_1, ret_number, f_foldclosed}, ! {"foldclosedend", 1, 1, FEARG_1, ret_number, f_foldclosedend}, ! {"foldlevel", 1, 1, FEARG_1, ret_number, f_foldlevel}, ! {"foldtext", 0, 0, 0, ret_string, f_foldtext}, ! {"foldtextresult", 1, 1, FEARG_1, ret_string, f_foldtextresult}, ! {"foreground", 0, 0, 0, ret_void, f_foreground}, ! {"funcref", 1, 3, FEARG_1, ret_func_any, f_funcref}, ! {"function", 1, 3, FEARG_1, ret_f_function, f_function}, ! {"garbagecollect", 0, 1, 0, ret_void, f_garbagecollect}, ! {"get", 2, 3, FEARG_1, ret_any, f_get}, ! {"getbufinfo", 0, 1, FEARG_1, ret_list_dict_any, f_getbufinfo}, ! {"getbufline", 2, 3, FEARG_1, ret_list_string, f_getbufline}, ! {"getbufvar", 2, 3, FEARG_1, ret_any, f_getbufvar}, ! {"getchangelist", 0, 1, FEARG_1, ret_list_any, f_getchangelist}, ! {"getchar", 0, 1, 0, ret_number, f_getchar}, ! {"getcharmod", 0, 0, 0, ret_number, f_getcharmod}, ! {"getcharsearch", 0, 0, 0, ret_dict_any, f_getcharsearch}, ! {"getcmdline", 0, 0, 0, ret_string, f_getcmdline}, ! {"getcmdpos", 0, 0, 0, ret_number, f_getcmdpos}, ! {"getcmdtype", 0, 0, 0, ret_string, f_getcmdtype}, ! {"getcmdwintype", 0, 0, 0, ret_string, f_getcmdwintype}, ! {"getcompletion", 2, 3, FEARG_1, ret_list_string, f_getcompletion}, ! {"getcurpos", 0, 1, FEARG_1, ret_list_number, f_getcurpos}, ! {"getcwd", 0, 2, FEARG_1, ret_string, f_getcwd}, ! {"getenv", 1, 1, FEARG_1, ret_string, f_getenv}, ! {"getfontname", 0, 1, 0, ret_string, f_getfontname}, ! {"getfperm", 1, 1, FEARG_1, ret_string, f_getfperm}, ! {"getfsize", 1, 1, FEARG_1, ret_number, f_getfsize}, ! {"getftime", 1, 1, FEARG_1, ret_number, f_getftime}, ! {"getftype", 1, 1, FEARG_1, ret_string, f_getftype}, ! {"getimstatus", 0, 0, 0, ret_number, f_getimstatus}, ! {"getjumplist", 0, 2, FEARG_1, ret_list_any, f_getjumplist}, ! {"getline", 1, 2, FEARG_1, ret_f_getline, f_getline}, ! {"getloclist", 1, 2, 0, ret_list_or_dict_1, f_getloclist}, ! {"getmarklist", 0, 1, FEARG_1, ret_list_dict_any, f_getmarklist}, ! {"getmatches", 0, 1, 0, ret_list_dict_any, f_getmatches}, ! {"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos}, ! {"getpid", 0, 0, 0, ret_number, f_getpid}, ! {"getpos", 1, 1, FEARG_1, ret_list_number, f_getpos}, ! {"getqflist", 0, 1, 0, ret_list_or_dict_0, f_getqflist}, ! {"getreg", 0, 3, FEARG_1, ret_getreg, f_getreg}, ! {"getreginfo", 0, 1, FEARG_1, ret_dict_any, f_getreginfo}, ! {"getregtype", 0, 1, FEARG_1, ret_string, f_getregtype}, ! {"gettabinfo", 0, 1, FEARG_1, ret_list_dict_any, f_gettabinfo}, ! {"gettabvar", 2, 3, FEARG_1, ret_any, f_gettabvar}, ! {"gettabwinvar", 3, 4, FEARG_1, ret_any, f_gettabwinvar}, ! {"gettagstack", 0, 1, FEARG_1, ret_dict_any, f_gettagstack}, ! {"gettext", 1, 1, FEARG_1, ret_string, f_gettext}, ! {"getwininfo", 0, 1, FEARG_1, ret_list_dict_any, f_getwininfo}, ! {"getwinpos", 0, 1, FEARG_1, ret_list_number, f_getwinpos}, ! {"getwinposx", 0, 0, 0, ret_number, f_getwinposx}, ! {"getwinposy", 0, 0, 0, ret_number, f_getwinposy}, ! {"getwinvar", 2, 3, FEARG_1, ret_any, f_getwinvar}, ! {"glob", 1, 4, FEARG_1, ret_any, f_glob}, ! {"glob2regpat", 1, 1, FEARG_1, ret_string, f_glob2regpat}, ! {"globpath", 2, 5, FEARG_2, ret_any, f_globpath}, ! {"has", 1, 2, 0, ret_number, f_has}, ! {"has_key", 2, 2, FEARG_1, ret_number, f_has_key}, ! {"haslocaldir", 0, 2, FEARG_1, ret_number, f_haslocaldir}, ! {"hasmapto", 1, 3, FEARG_1, ret_number, f_hasmapto}, ! {"highlightID", 1, 1, FEARG_1, ret_number, f_hlID}, // obsolete ! {"highlight_exists",1, 1, FEARG_1, ret_number, f_hlexists}, // obsolete ! {"histadd", 2, 2, FEARG_2, ret_number, f_histadd}, ! {"histdel", 1, 2, FEARG_1, ret_number, f_histdel}, ! {"histget", 1, 2, FEARG_1, ret_string, f_histget}, ! {"histnr", 1, 1, FEARG_1, ret_number, f_histnr}, ! {"hlID", 1, 1, FEARG_1, ret_number, f_hlID}, ! {"hlexists", 1, 1, FEARG_1, ret_number, f_hlexists}, ! {"hostname", 0, 0, 0, ret_string, f_hostname}, ! {"iconv", 3, 3, FEARG_1, ret_string, f_iconv}, ! {"indent", 1, 1, FEARG_1, ret_number, f_indent}, ! {"index", 2, 4, FEARG_1, ret_number, f_index}, ! {"input", 1, 3, FEARG_1, ret_string, f_input}, ! {"inputdialog", 1, 3, FEARG_1, ret_string, f_inputdialog}, ! {"inputlist", 1, 1, FEARG_1, ret_number, f_inputlist}, ! {"inputrestore", 0, 0, 0, ret_number, f_inputrestore}, ! {"inputsave", 0, 0, 0, ret_number, f_inputsave}, ! {"inputsecret", 1, 2, FEARG_1, ret_string, f_inputsecret}, ! {"insert", 2, 3, FEARG_1, ret_first_arg, f_insert}, ! {"interrupt", 0, 0, 0, ret_void, f_interrupt}, ! {"invert", 1, 1, FEARG_1, ret_number, f_invert}, ! {"isdirectory", 1, 1, FEARG_1, ret_number, f_isdirectory}, ! {"isinf", 1, 1, FEARG_1, ret_number, MATH_FUNC(f_isinf)}, ! {"islocked", 1, 1, FEARG_1, ret_number, f_islocked}, ! {"isnan", 1, 1, FEARG_1, ret_number, MATH_FUNC(f_isnan)}, ! {"items", 1, 1, FEARG_1, ret_list_any, f_items}, ! {"job_getchannel", 1, 1, FEARG_1, ret_channel, JOB_FUNC(f_job_getchannel)}, ! {"job_info", 0, 1, FEARG_1, ret_dict_any, JOB_FUNC(f_job_info)}, ! {"job_setoptions", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_job_setoptions)}, ! {"job_start", 1, 2, FEARG_1, ret_job, JOB_FUNC(f_job_start)}, ! {"job_status", 1, 1, FEARG_1, ret_string, JOB_FUNC(f_job_status)}, ! {"job_stop", 1, 2, FEARG_1, ret_number, JOB_FUNC(f_job_stop)}, ! {"join", 1, 2, FEARG_1, ret_string, f_join}, ! {"js_decode", 1, 1, FEARG_1, ret_any, f_js_decode}, ! {"js_encode", 1, 1, FEARG_1, ret_string, f_js_encode}, ! {"json_decode", 1, 1, FEARG_1, ret_any, f_json_decode}, ! {"json_encode", 1, 1, FEARG_1, ret_string, f_json_encode}, ! {"keys", 1, 1, FEARG_1, ret_list_string, f_keys}, ! {"last_buffer_nr", 0, 0, 0, ret_number, f_last_buffer_nr}, // obsolete ! {"len", 1, 1, FEARG_1, ret_number, f_len}, ! {"libcall", 3, 3, FEARG_3, ret_string, f_libcall}, ! {"libcallnr", 3, 3, FEARG_3, ret_number, f_libcallnr}, ! {"line", 1, 2, FEARG_1, ret_number, f_line}, ! {"line2byte", 1, 1, FEARG_1, ret_number, f_line2byte}, ! {"lispindent", 1, 1, FEARG_1, ret_number, f_lispindent}, ! {"list2str", 1, 2, FEARG_1, ret_string, f_list2str}, ! {"listener_add", 1, 2, FEARG_2, ret_number, f_listener_add}, ! {"listener_flush", 0, 1, FEARG_1, ret_void, f_listener_flush}, ! {"listener_remove", 1, 1, FEARG_1, ret_number, f_listener_remove}, ! {"localtime", 0, 0, 0, ret_number, f_localtime}, ! {"log", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_log)}, ! {"log10", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_log10)}, ! {"luaeval", 1, 2, FEARG_1, ret_any, #ifdef FEAT_LUA f_luaeval #else NULL #endif }, ! {"map", 2, 2, FEARG_1, ret_any, f_map}, ! {"maparg", 1, 4, FEARG_1, ret_maparg, f_maparg}, ! {"mapcheck", 1, 3, FEARG_1, ret_string, f_mapcheck}, ! {"mapset", 3, 3, FEARG_1, ret_void, f_mapset}, ! {"match", 2, 4, FEARG_1, ret_any, f_match}, ! {"matchadd", 2, 5, FEARG_1, ret_number, f_matchadd}, ! {"matchaddpos", 2, 5, FEARG_1, ret_number, f_matchaddpos}, ! {"matcharg", 1, 1, FEARG_1, ret_list_string, f_matcharg}, ! {"matchdelete", 1, 2, FEARG_1, ret_number, f_matchdelete}, ! {"matchend", 2, 4, FEARG_1, ret_number, f_matchend}, ! {"matchfuzzy", 2, 3, FEARG_1, ret_list_string, f_matchfuzzy}, ! {"matchfuzzypos", 2, 3, FEARG_1, ret_list_any, f_matchfuzzypos}, ! {"matchlist", 2, 4, FEARG_1, ret_list_string, f_matchlist}, ! {"matchstr", 2, 4, FEARG_1, ret_string, f_matchstr}, ! {"matchstrpos", 2, 4, FEARG_1, ret_list_any, f_matchstrpos}, ! {"max", 1, 1, FEARG_1, ret_any, f_max}, ! {"menu_info", 1, 2, FEARG_1, ret_dict_any, #ifdef FEAT_MENU f_menu_info #else NULL #endif }, ! {"min", 1, 1, FEARG_1, ret_any, f_min}, ! {"mkdir", 1, 3, FEARG_1, ret_number, f_mkdir}, ! {"mode", 0, 1, FEARG_1, ret_string, f_mode}, ! {"mzeval", 1, 1, FEARG_1, ret_any, #ifdef FEAT_MZSCHEME f_mzeval #else NULL #endif }, ! {"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank}, ! {"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char}, ! {"or", 2, 2, FEARG_1, ret_number, f_or}, ! {"pathshorten", 1, 2, FEARG_1, ret_string, f_pathshorten}, ! {"perleval", 1, 1, FEARG_1, ret_any, #ifdef FEAT_PERL f_perleval #else NULL #endif }, ! {"popup_atcursor", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_atcursor)}, ! {"popup_beval", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_beval)}, ! {"popup_clear", 0, 1, 0, ret_void, PROP_FUNC(f_popup_clear)}, ! {"popup_close", 1, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_close)}, ! {"popup_create", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_create)}, ! {"popup_dialog", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_dialog)}, ! {"popup_filter_menu", 2, 2, 0, ret_bool, PROP_FUNC(f_popup_filter_menu)}, ! {"popup_filter_yesno", 2, 2, 0, ret_bool, PROP_FUNC(f_popup_filter_yesno)}, ! {"popup_findinfo", 0, 0, 0, ret_number, PROP_FUNC(f_popup_findinfo)}, ! {"popup_findpreview", 0, 0, 0, ret_number, PROP_FUNC(f_popup_findpreview)}, ! {"popup_getoptions", 1, 1, FEARG_1, ret_dict_any, PROP_FUNC(f_popup_getoptions)}, ! {"popup_getpos", 1, 1, FEARG_1, ret_dict_any, PROP_FUNC(f_popup_getpos)}, ! {"popup_hide", 1, 1, FEARG_1, ret_void, PROP_FUNC(f_popup_hide)}, ! {"popup_list", 0, 0, 0, ret_list_number, PROP_FUNC(f_popup_list)}, ! {"popup_locate", 2, 2, 0, ret_number, PROP_FUNC(f_popup_locate)}, ! {"popup_menu", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_menu)}, ! {"popup_move", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_move)}, ! {"popup_notification", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_notification)}, ! {"popup_setoptions", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_setoptions)}, ! {"popup_settext", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_settext)}, ! {"popup_show", 1, 1, FEARG_1, ret_void, PROP_FUNC(f_popup_show)}, ! {"pow", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_pow)}, ! {"prevnonblank", 1, 1, FEARG_1, ret_number, f_prevnonblank}, ! {"printf", 1, 19, FEARG_2, ret_string, f_printf}, ! {"prompt_getprompt", 1, 1, FEARG_1, ret_string, JOB_FUNC(f_prompt_getprompt)}, ! {"prompt_setcallback", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_prompt_setcallback)}, ! {"prompt_setinterrupt", 2, 2, FEARG_1,ret_void, JOB_FUNC(f_prompt_setinterrupt)}, ! {"prompt_setprompt", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_prompt_setprompt)}, ! {"prop_add", 3, 3, FEARG_1, ret_void, PROP_FUNC(f_prop_add)}, ! {"prop_clear", 1, 3, FEARG_1, ret_void, PROP_FUNC(f_prop_clear)}, ! {"prop_find", 1, 2, FEARG_1, ret_dict_any, PROP_FUNC(f_prop_find)}, ! {"prop_list", 1, 2, FEARG_1, ret_list_dict_any, PROP_FUNC(f_prop_list)}, ! {"prop_remove", 1, 3, FEARG_1, ret_number, PROP_FUNC(f_prop_remove)}, ! {"prop_type_add", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_add)}, ! {"prop_type_change", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_change)}, ! {"prop_type_delete", 1, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_delete)}, ! {"prop_type_get", 1, 2, FEARG_1, ret_dict_any, PROP_FUNC(f_prop_type_get)}, ! {"prop_type_list", 0, 1, FEARG_1, ret_list_string, PROP_FUNC(f_prop_type_list)}, ! {"pum_getpos", 0, 0, 0, ret_dict_number, f_pum_getpos}, ! {"pumvisible", 0, 0, 0, ret_number, f_pumvisible}, ! {"py3eval", 1, 1, FEARG_1, ret_any, #ifdef FEAT_PYTHON3 f_py3eval #else NULL #endif }, ! {"pyeval", 1, 1, FEARG_1, ret_any, #ifdef FEAT_PYTHON f_pyeval #else NULL #endif }, ! {"pyxeval", 1, 1, FEARG_1, ret_any, #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) f_pyxeval #else NULL #endif }, ! {"rand", 0, 1, FEARG_1, ret_number, f_rand}, ! {"range", 1, 3, FEARG_1, ret_list_number, f_range}, ! {"readdir", 1, 3, FEARG_1, ret_list_string, f_readdir}, ! {"readdirex", 1, 3, FEARG_1, ret_list_dict_any, f_readdirex}, ! {"readfile", 1, 3, FEARG_1, ret_any, f_readfile}, ! {"reduce", 2, 3, FEARG_1, ret_any, f_reduce}, ! {"reg_executing", 0, 0, 0, ret_string, f_reg_executing}, ! {"reg_recording", 0, 0, 0, ret_string, f_reg_recording}, ! {"reltime", 0, 2, FEARG_1, ret_list_any, f_reltime}, ! {"reltimefloat", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_reltimefloat)}, ! {"reltimestr", 1, 1, FEARG_1, ret_string, f_reltimestr}, ! {"remote_expr", 2, 4, FEARG_1, ret_string, f_remote_expr}, ! {"remote_foreground", 1, 1, FEARG_1, ret_string, f_remote_foreground}, ! {"remote_peek", 1, 2, FEARG_1, ret_number, f_remote_peek}, ! {"remote_read", 1, 2, FEARG_1, ret_string, f_remote_read}, ! {"remote_send", 2, 3, FEARG_1, ret_string, f_remote_send}, ! {"remote_startserver", 1, 1, FEARG_1, ret_void, f_remote_startserver}, ! {"remove", 2, 3, FEARG_1, ret_remove, f_remove}, ! {"rename", 2, 2, FEARG_1, ret_number, f_rename}, ! {"repeat", 2, 2, FEARG_1, ret_first_arg, f_repeat}, ! {"resolve", 1, 1, FEARG_1, ret_string, f_resolve}, ! {"reverse", 1, 1, FEARG_1, ret_first_arg, f_reverse}, ! {"round", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_round)}, ! {"rubyeval", 1, 1, FEARG_1, ret_any, #ifdef FEAT_RUBY f_rubyeval #else NULL #endif }, ! {"screenattr", 2, 2, FEARG_1, ret_number, f_screenattr}, ! {"screenchar", 2, 2, FEARG_1, ret_number, f_screenchar}, ! {"screenchars", 2, 2, FEARG_1, ret_list_number, f_screenchars}, ! {"screencol", 0, 0, 0, ret_number, f_screencol}, ! {"screenpos", 3, 3, FEARG_1, ret_dict_number, f_screenpos}, ! {"screenrow", 0, 0, 0, ret_number, f_screenrow}, ! {"screenstring", 2, 2, FEARG_1, ret_string, f_screenstring}, ! {"search", 1, 5, FEARG_1, ret_number, f_search}, ! {"searchcount", 0, 1, FEARG_1, ret_dict_any, f_searchcount}, ! {"searchdecl", 1, 3, FEARG_1, ret_number, f_searchdecl}, ! {"searchpair", 3, 7, 0, ret_number, f_searchpair}, ! {"searchpairpos", 3, 7, 0, ret_list_number, f_searchpairpos}, ! {"searchpos", 1, 5, FEARG_1, ret_list_number, f_searchpos}, ! {"server2client", 2, 2, FEARG_1, ret_number, f_server2client}, ! {"serverlist", 0, 0, 0, ret_string, f_serverlist}, ! {"setbufline", 3, 3, FEARG_3, ret_number, f_setbufline}, ! {"setbufvar", 3, 3, FEARG_3, ret_void, f_setbufvar}, ! {"setcellwidths", 1, 1, FEARG_1, ret_void, f_setcellwidths}, ! {"setcharsearch", 1, 1, FEARG_1, ret_void, f_setcharsearch}, ! {"setcmdpos", 1, 1, FEARG_1, ret_number, f_setcmdpos}, ! {"setenv", 2, 2, FEARG_2, ret_void, f_setenv}, ! {"setfperm", 2, 2, FEARG_1, ret_number, f_setfperm}, ! {"setline", 2, 2, FEARG_2, ret_number, f_setline}, ! {"setloclist", 2, 4, FEARG_2, ret_number, f_setloclist}, ! {"setmatches", 1, 2, FEARG_1, ret_number, f_setmatches}, ! {"setpos", 2, 2, FEARG_2, ret_number, f_setpos}, ! {"setqflist", 1, 3, FEARG_1, ret_number, f_setqflist}, ! {"setreg", 2, 3, FEARG_2, ret_number, f_setreg}, ! {"settabvar", 3, 3, FEARG_3, ret_void, f_settabvar}, ! {"settabwinvar", 4, 4, FEARG_4, ret_void, f_settabwinvar}, ! {"settagstack", 2, 3, FEARG_2, ret_number, f_settagstack}, ! {"setwinvar", 3, 3, FEARG_3, ret_void, f_setwinvar}, ! {"sha256", 1, 1, FEARG_1, ret_string, #ifdef FEAT_CRYPT f_sha256 #else NULL #endif }, ! {"shellescape", 1, 2, FEARG_1, ret_string, f_shellescape}, ! {"shiftwidth", 0, 1, FEARG_1, ret_number, f_shiftwidth}, ! {"sign_define", 1, 2, FEARG_1, ret_any, SIGN_FUNC(f_sign_define)}, ! {"sign_getdefined", 0, 1, FEARG_1, ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)}, ! {"sign_getplaced", 0, 2, FEARG_1, ret_list_dict_any, SIGN_FUNC(f_sign_getplaced)}, ! {"sign_jump", 3, 3, FEARG_1, ret_number, SIGN_FUNC(f_sign_jump)}, ! {"sign_place", 4, 5, FEARG_1, ret_number, SIGN_FUNC(f_sign_place)}, ! {"sign_placelist", 1, 1, FEARG_1, ret_list_number, SIGN_FUNC(f_sign_placelist)}, ! {"sign_undefine", 0, 1, FEARG_1, ret_number, SIGN_FUNC(f_sign_undefine)}, ! {"sign_unplace", 1, 2, FEARG_1, ret_number, SIGN_FUNC(f_sign_unplace)}, ! {"sign_unplacelist", 1, 2, FEARG_1, ret_list_number, SIGN_FUNC(f_sign_unplacelist)}, ! {"simplify", 1, 1, FEARG_1, ret_string, f_simplify}, ! {"sin", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sin)}, ! {"sinh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sinh)}, ! {"sort", 1, 3, FEARG_1, ret_first_arg, f_sort}, ! {"sound_clear", 0, 0, 0, ret_void, SOUND_FUNC(f_sound_clear)}, ! {"sound_playevent", 1, 2, FEARG_1, ret_number, SOUND_FUNC(f_sound_playevent)}, ! {"sound_playfile", 1, 2, FEARG_1, ret_number, SOUND_FUNC(f_sound_playfile)}, ! {"sound_stop", 1, 1, FEARG_1, ret_void, SOUND_FUNC(f_sound_stop)}, ! {"soundfold", 1, 1, FEARG_1, ret_string, f_soundfold}, ! {"spellbadword", 0, 1, FEARG_1, ret_list_string, f_spellbadword}, ! {"spellsuggest", 1, 3, FEARG_1, ret_list_string, f_spellsuggest}, ! {"split", 1, 3, FEARG_1, ret_list_string, f_split}, ! {"sqrt", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sqrt)}, ! {"srand", 0, 1, FEARG_1, ret_list_number, f_srand}, ! {"state", 0, 1, FEARG_1, ret_string, f_state}, ! {"str2float", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_str2float)}, ! {"str2list", 1, 2, FEARG_1, ret_list_number, f_str2list}, ! {"str2nr", 1, 3, FEARG_1, ret_number, f_str2nr}, ! {"strcharpart", 2, 3, FEARG_1, ret_string, f_strcharpart}, ! {"strchars", 1, 2, FEARG_1, ret_number, f_strchars}, ! {"strdisplaywidth", 1, 2, FEARG_1, ret_number, f_strdisplaywidth}, ! {"strftime", 1, 2, FEARG_1, ret_string, #ifdef HAVE_STRFTIME f_strftime #else NULL #endif }, ! {"strgetchar", 2, 2, FEARG_1, ret_number, f_strgetchar}, ! {"stridx", 2, 3, FEARG_1, ret_number, f_stridx}, ! {"string", 1, 1, FEARG_1, ret_string, f_string}, ! {"strlen", 1, 1, FEARG_1, ret_number, f_strlen}, ! {"strpart", 2, 4, FEARG_1, ret_string, f_strpart}, ! {"strptime", 2, 2, FEARG_1, ret_number, #ifdef HAVE_STRPTIME f_strptime #else NULL #endif }, ! {"strridx", 2, 3, FEARG_1, ret_number, f_strridx}, ! {"strtrans", 1, 1, FEARG_1, ret_string, f_strtrans}, ! {"strwidth", 1, 1, FEARG_1, ret_number, f_strwidth}, ! {"submatch", 1, 2, FEARG_1, ret_string, f_submatch}, ! {"substitute", 4, 4, FEARG_1, ret_string, f_substitute}, ! {"swapinfo", 1, 1, FEARG_1, ret_dict_any, f_swapinfo}, ! {"swapname", 1, 1, FEARG_1, ret_string, f_swapname}, ! {"synID", 3, 3, 0, ret_number, f_synID}, ! {"synIDattr", 2, 3, FEARG_1, ret_string, f_synIDattr}, ! {"synIDtrans", 1, 1, FEARG_1, ret_number, f_synIDtrans}, ! {"synconcealed", 2, 2, 0, ret_list_any, f_synconcealed}, ! {"synstack", 2, 2, 0, ret_list_number, f_synstack}, ! {"system", 1, 2, FEARG_1, ret_string, f_system}, ! {"systemlist", 1, 2, FEARG_1, ret_list_string, f_systemlist}, ! {"tabpagebuflist", 0, 1, FEARG_1, ret_list_number, f_tabpagebuflist}, ! {"tabpagenr", 0, 1, 0, ret_number, f_tabpagenr}, ! {"tabpagewinnr", 1, 2, FEARG_1, ret_number, f_tabpagewinnr}, ! {"tagfiles", 0, 0, 0, ret_list_string, f_tagfiles}, ! {"taglist", 1, 2, FEARG_1, ret_list_dict_any, f_taglist}, ! {"tan", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_tan)}, ! {"tanh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_tanh)}, ! {"tempname", 0, 0, 0, ret_string, f_tempname}, ! {"term_dumpdiff", 2, 3, FEARG_1, ret_number, TERM_FUNC(f_term_dumpdiff)}, ! {"term_dumpload", 1, 2, FEARG_1, ret_number, TERM_FUNC(f_term_dumpload)}, ! {"term_dumpwrite", 2, 3, FEARG_2, ret_void, TERM_FUNC(f_term_dumpwrite)}, ! {"term_getaltscreen", 1, 1, FEARG_1, ret_number, TERM_FUNC(f_term_getaltscreen)}, ! {"term_getansicolors", 1, 1, FEARG_1, ret_list_string, #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) f_term_getansicolors #else NULL #endif }, ! {"term_getattr", 2, 2, FEARG_1, ret_number, TERM_FUNC(f_term_getattr)}, ! {"term_getcursor", 1, 1, FEARG_1, ret_list_any, TERM_FUNC(f_term_getcursor)}, ! {"term_getjob", 1, 1, FEARG_1, ret_job, TERM_FUNC(f_term_getjob)}, ! {"term_getline", 2, 2, FEARG_1, ret_string, TERM_FUNC(f_term_getline)}, ! {"term_getscrolled", 1, 1, FEARG_1, ret_number, TERM_FUNC(f_term_getscrolled)}, ! {"term_getsize", 1, 1, FEARG_1, ret_list_number, TERM_FUNC(f_term_getsize)}, ! {"term_getstatus", 1, 1, FEARG_1, ret_string, TERM_FUNC(f_term_getstatus)}, ! {"term_gettitle", 1, 1, FEARG_1, ret_string, TERM_FUNC(f_term_gettitle)}, ! {"term_gettty", 1, 2, FEARG_1, ret_string, TERM_FUNC(f_term_gettty)}, ! {"term_list", 0, 0, 0, ret_list_number, TERM_FUNC(f_term_list)}, ! {"term_scrape", 2, 2, FEARG_1, ret_list_dict_any, TERM_FUNC(f_term_scrape)}, ! {"term_sendkeys", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_sendkeys)}, ! {"term_setansicolors", 2, 2, FEARG_1, ret_void, #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) f_term_setansicolors #else NULL #endif }, ! {"term_setapi", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setapi)}, ! {"term_setkill", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setkill)}, ! {"term_setrestore", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setrestore)}, ! {"term_setsize", 3, 3, FEARG_1, ret_void, TERM_FUNC(f_term_setsize)}, ! {"term_start", 1, 2, FEARG_1, ret_number, TERM_FUNC(f_term_start)}, ! {"term_wait", 1, 2, FEARG_1, ret_void, TERM_FUNC(f_term_wait)}, ! {"terminalprops", 0, 0, 0, ret_dict_string, f_terminalprops}, ! {"test_alloc_fail", 3, 3, FEARG_1, ret_void, f_test_alloc_fail}, ! {"test_autochdir", 0, 0, 0, ret_void, f_test_autochdir}, ! {"test_feedinput", 1, 1, FEARG_1, ret_void, f_test_feedinput}, ! {"test_garbagecollect_now", 0, 0, 0, ret_void, f_test_garbagecollect_now}, ! {"test_garbagecollect_soon", 0, 0, 0, ret_void, f_test_garbagecollect_soon}, ! {"test_getvalue", 1, 1, FEARG_1, ret_number, f_test_getvalue}, ! {"test_ignore_error", 1, 1, FEARG_1, ret_void, f_test_ignore_error}, ! {"test_null_blob", 0, 0, 0, ret_blob, f_test_null_blob}, ! {"test_null_channel", 0, 0, 0, ret_channel, JOB_FUNC(f_test_null_channel)}, ! {"test_null_dict", 0, 0, 0, ret_dict_any, f_test_null_dict}, ! {"test_null_function", 0, 0, 0, ret_func_any, f_test_null_function}, ! {"test_null_job", 0, 0, 0, ret_job, JOB_FUNC(f_test_null_job)}, ! {"test_null_list", 0, 0, 0, ret_list_any, f_test_null_list}, ! {"test_null_partial", 0, 0, 0, ret_func_any, f_test_null_partial}, ! {"test_null_string", 0, 0, 0, ret_string, f_test_null_string}, ! {"test_option_not_set", 1, 1, FEARG_1,ret_void, f_test_option_not_set}, ! {"test_override", 2, 2, FEARG_2, ret_void, f_test_override}, ! {"test_refcount", 1, 1, FEARG_1, ret_number, f_test_refcount}, ! {"test_scrollbar", 3, 3, FEARG_2, ret_void, #ifdef FEAT_GUI f_test_scrollbar #else NULL #endif }, ! {"test_setmouse", 2, 2, 0, ret_void, f_test_setmouse}, ! {"test_settime", 1, 1, FEARG_1, ret_void, f_test_settime}, ! {"test_srand_seed", 0, 1, FEARG_1, ret_void, f_test_srand_seed}, ! {"test_unknown", 0, 0, 0, ret_any, f_test_unknown}, ! {"test_void", 0, 0, 0, ret_void, f_test_void}, ! {"timer_info", 0, 1, FEARG_1, ret_list_dict_any, TIMER_FUNC(f_timer_info)}, ! {"timer_pause", 2, 2, FEARG_1, ret_void, TIMER_FUNC(f_timer_pause)}, ! {"timer_start", 2, 3, FEARG_1, ret_number, TIMER_FUNC(f_timer_start)}, ! {"timer_stop", 1, 1, FEARG_1, ret_void, TIMER_FUNC(f_timer_stop)}, ! {"timer_stopall", 0, 0, 0, ret_void, TIMER_FUNC(f_timer_stopall)}, ! {"tolower", 1, 1, FEARG_1, ret_string, f_tolower}, ! {"toupper", 1, 1, FEARG_1, ret_string, f_toupper}, ! {"tr", 3, 3, FEARG_1, ret_string, f_tr}, ! {"trim", 1, 3, FEARG_1, ret_string, f_trim}, ! {"trunc", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_trunc)}, ! {"type", 1, 1, FEARG_1, ret_number, f_type}, ! {"undofile", 1, 1, FEARG_1, ret_string, f_undofile}, ! {"undotree", 0, 0, 0, ret_dict_any, f_undotree}, ! {"uniq", 1, 3, FEARG_1, ret_list_any, f_uniq}, ! {"values", 1, 1, FEARG_1, ret_list_any, f_values}, ! {"virtcol", 1, 1, FEARG_1, ret_number, f_virtcol}, ! {"visualmode", 0, 1, 0, ret_string, f_visualmode}, ! {"wildmenumode", 0, 0, 0, ret_number, f_wildmenumode}, ! {"win_execute", 2, 3, FEARG_2, ret_string, f_win_execute}, ! {"win_findbuf", 1, 1, FEARG_1, ret_list_number, f_win_findbuf}, ! {"win_getid", 0, 2, FEARG_1, ret_number, f_win_getid}, ! {"win_gettype", 0, 1, FEARG_1, ret_string, f_win_gettype}, ! {"win_gotoid", 1, 1, FEARG_1, ret_number, f_win_gotoid}, ! {"win_id2tabwin", 1, 1, FEARG_1, ret_list_number, f_win_id2tabwin}, ! {"win_id2win", 1, 1, FEARG_1, ret_number, f_win_id2win}, ! {"win_screenpos", 1, 1, FEARG_1, ret_list_number, f_win_screenpos}, ! {"win_splitmove", 2, 3, FEARG_1, ret_number, f_win_splitmove}, ! {"winbufnr", 1, 1, FEARG_1, ret_number, f_winbufnr}, ! {"wincol", 0, 0, 0, ret_number, f_wincol}, ! {"windowsversion", 0, 0, 0, ret_string, f_windowsversion}, ! {"winheight", 1, 1, FEARG_1, ret_number, f_winheight}, ! {"winlayout", 0, 1, FEARG_1, ret_list_any, f_winlayout}, ! {"winline", 0, 0, 0, ret_number, f_winline}, ! {"winnr", 0, 1, FEARG_1, ret_number, f_winnr}, ! {"winrestcmd", 0, 0, 0, ret_string, f_winrestcmd}, ! {"winrestview", 1, 1, FEARG_1, ret_void, f_winrestview}, ! {"winsaveview", 0, 0, 0, ret_dict_any, f_winsaveview}, ! {"winwidth", 1, 1, FEARG_1, ret_number, f_winwidth}, ! {"wordcount", 0, 0, 0, ret_dict_number, f_wordcount}, ! {"writefile", 2, 3, FEARG_1, ret_number, f_writefile}, ! {"xor", 2, 2, FEARG_1, ret_number, f_xor}, }; /* --- 522,1649 ---- static funcentry_T global_functions[] = { ! {"abs", 1, 1, FEARG_1, arg1_float_or_nr, ! ret_any, FLOAT_FUNC(f_abs)}, ! {"acos", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_acos)}, ! {"add", 2, 2, FEARG_1, NULL, ! ret_first_arg, f_add}, ! {"and", 2, 2, FEARG_1, NULL, ! ret_number, f_and}, ! {"append", 2, 2, FEARG_2, NULL, ! ret_number, f_append}, ! {"appendbufline", 3, 3, FEARG_3, NULL, ! ret_number, f_appendbufline}, ! {"argc", 0, 1, 0, NULL, ! ret_number, f_argc}, ! {"argidx", 0, 0, 0, NULL, ! ret_number, f_argidx}, ! {"arglistid", 0, 2, 0, NULL, ! ret_number, f_arglistid}, ! {"argv", 0, 2, 0, NULL, ! ret_argv, f_argv}, ! {"asin", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_asin)}, ! {"assert_beeps", 1, 2, FEARG_1, NULL, ! ret_number, f_assert_beeps}, ! {"assert_equal", 2, 3, FEARG_2, NULL, ! ret_number, f_assert_equal}, ! {"assert_equalfile", 2, 3, FEARG_1, NULL, ! ret_number, f_assert_equalfile}, ! {"assert_exception", 1, 2, 0, NULL, ! ret_number, f_assert_exception}, ! {"assert_fails", 1, 5, FEARG_1, NULL, ! ret_number, f_assert_fails}, ! {"assert_false", 1, 2, FEARG_1, NULL, ! ret_number, f_assert_false}, ! {"assert_inrange", 3, 4, FEARG_3, NULL, ! ret_number, f_assert_inrange}, ! {"assert_match", 2, 3, FEARG_2, NULL, ! ret_number, f_assert_match}, ! {"assert_notequal", 2, 3, FEARG_2, NULL, ! ret_number, f_assert_notequal}, ! {"assert_notmatch", 2, 3, FEARG_2, NULL, ! ret_number, f_assert_notmatch}, ! {"assert_report", 1, 1, FEARG_1, NULL, ! ret_number, f_assert_report}, ! {"assert_true", 1, 2, FEARG_1, NULL, ! ret_number, f_assert_true}, ! {"atan", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_atan)}, ! {"atan2", 2, 2, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_atan2)}, ! {"balloon_gettext", 0, 0, 0, NULL, ! ret_string, #ifdef FEAT_BEVAL f_balloon_gettext #else NULL #endif }, ! {"balloon_show", 1, 1, FEARG_1, NULL, ! ret_void, #ifdef FEAT_BEVAL f_balloon_show #else NULL #endif }, ! {"balloon_split", 1, 1, FEARG_1, NULL, ! ret_list_string, #if defined(FEAT_BEVAL_TERM) f_balloon_split #else NULL #endif }, ! {"browse", 4, 4, 0, NULL, ! ret_string, f_browse}, ! {"browsedir", 2, 2, 0, NULL, ! ret_string, f_browsedir}, ! {"bufadd", 1, 1, FEARG_1, NULL, ! ret_number, f_bufadd}, ! {"bufexists", 1, 1, FEARG_1, NULL, ! ret_number, f_bufexists}, ! {"buffer_exists", 1, 1, FEARG_1, NULL, ! ret_number, f_bufexists}, // obsolete ! {"buffer_name", 0, 1, FEARG_1, NULL, ! ret_string, f_bufname}, // obsolete ! {"buffer_number", 0, 1, FEARG_1, NULL, ! ret_number, f_bufnr}, // obsolete ! {"buflisted", 1, 1, FEARG_1, NULL, ! ret_number, f_buflisted}, ! {"bufload", 1, 1, FEARG_1, NULL, ! ret_void, f_bufload}, ! {"bufloaded", 1, 1, FEARG_1, NULL, ! ret_number, f_bufloaded}, ! {"bufname", 0, 1, FEARG_1, NULL, ! ret_string, f_bufname}, ! {"bufnr", 0, 2, FEARG_1, NULL, ! ret_number, f_bufnr}, ! {"bufwinid", 1, 1, FEARG_1, NULL, ! ret_number, f_bufwinid}, ! {"bufwinnr", 1, 1, FEARG_1, NULL, ! ret_number, f_bufwinnr}, ! {"byte2line", 1, 1, FEARG_1, NULL, ! ret_number, f_byte2line}, ! {"byteidx", 2, 2, FEARG_1, NULL, ! ret_number, f_byteidx}, ! {"byteidxcomp", 2, 2, FEARG_1, NULL, ! ret_number, f_byteidxcomp}, ! {"call", 2, 3, FEARG_1, NULL, ! ret_any, f_call}, ! {"ceil", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_ceil)}, ! {"ch_canread", 1, 1, FEARG_1, NULL, ! ret_number, JOB_FUNC(f_ch_canread)}, ! {"ch_close", 1, 1, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_close)}, ! {"ch_close_in", 1, 1, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_close_in)}, ! {"ch_evalexpr", 2, 3, FEARG_1, NULL, ! ret_any, JOB_FUNC(f_ch_evalexpr)}, ! {"ch_evalraw", 2, 3, FEARG_1, NULL, ! ret_any, JOB_FUNC(f_ch_evalraw)}, ! {"ch_getbufnr", 2, 2, FEARG_1, NULL, ! ret_number, JOB_FUNC(f_ch_getbufnr)}, ! {"ch_getjob", 1, 1, FEARG_1, NULL, ! ret_job, JOB_FUNC(f_ch_getjob)}, ! {"ch_info", 1, 1, FEARG_1, NULL, ! ret_dict_any, JOB_FUNC(f_ch_info)}, ! {"ch_log", 1, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_log)}, ! {"ch_logfile", 1, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_logfile)}, ! {"ch_open", 1, 2, FEARG_1, NULL, ! ret_channel, JOB_FUNC(f_ch_open)}, ! {"ch_read", 1, 2, FEARG_1, NULL, ! ret_string, JOB_FUNC(f_ch_read)}, ! {"ch_readblob", 1, 2, FEARG_1, NULL, ! ret_blob, JOB_FUNC(f_ch_readblob)}, ! {"ch_readraw", 1, 2, FEARG_1, NULL, ! ret_string, JOB_FUNC(f_ch_readraw)}, ! {"ch_sendexpr", 2, 3, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_sendexpr)}, ! {"ch_sendraw", 2, 3, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_sendraw)}, ! {"ch_setoptions", 2, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_ch_setoptions)}, ! {"ch_status", 1, 2, FEARG_1, NULL, ! ret_string, JOB_FUNC(f_ch_status)}, ! {"changenr", 0, 0, 0, NULL, ! ret_number, f_changenr}, ! {"char2nr", 1, 2, FEARG_1, NULL, ! ret_number, f_char2nr}, ! {"charclass", 1, 1, FEARG_1, NULL, ! ret_number, f_charclass}, ! {"chdir", 1, 1, FEARG_1, NULL, ! ret_string, f_chdir}, ! {"cindent", 1, 1, FEARG_1, NULL, ! ret_number, f_cindent}, ! {"clearmatches", 0, 1, FEARG_1, NULL, ! ret_void, f_clearmatches}, ! {"col", 1, 1, FEARG_1, NULL, ! ret_number, f_col}, ! {"complete", 2, 2, FEARG_2, NULL, ! ret_void, f_complete}, ! {"complete_add", 1, 1, FEARG_1, NULL, ! ret_number, f_complete_add}, ! {"complete_check", 0, 0, 0, NULL, ! ret_number, f_complete_check}, ! {"complete_info", 0, 1, FEARG_1, NULL, ! ret_dict_any, f_complete_info}, ! {"confirm", 1, 4, FEARG_1, NULL, ! ret_number, f_confirm}, ! {"copy", 1, 1, FEARG_1, NULL, ! ret_first_arg, f_copy}, ! {"cos", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_cos)}, ! {"cosh", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_cosh)}, ! {"count", 2, 4, FEARG_1, NULL, ! ret_number, f_count}, ! {"cscope_connection",0,3, 0, NULL, ! ret_number, f_cscope_connection}, ! {"cursor", 1, 3, FEARG_1, NULL, ! ret_number, f_cursor}, ! {"debugbreak", 1, 1, FEARG_1, NULL, ! ret_number, #ifdef MSWIN f_debugbreak #else NULL #endif }, ! {"deepcopy", 1, 2, FEARG_1, NULL, ! ret_first_arg, f_deepcopy}, ! {"delete", 1, 2, FEARG_1, NULL, ! ret_number, f_delete}, ! {"deletebufline", 2, 3, FEARG_1, NULL, ! ret_number, f_deletebufline}, ! {"did_filetype", 0, 0, 0, NULL, ! ret_number, f_did_filetype}, ! {"diff_filler", 1, 1, FEARG_1, NULL, ! ret_number, f_diff_filler}, ! {"diff_hlID", 2, 2, FEARG_1, NULL, ! ret_number, f_diff_hlID}, ! {"echoraw", 1, 1, FEARG_1, NULL, ! ret_number, f_echoraw}, ! {"empty", 1, 1, FEARG_1, NULL, ! ret_number, f_empty}, ! {"environ", 0, 0, 0, NULL, ! ret_dict_string, f_environ}, ! {"escape", 2, 2, FEARG_1, NULL, ! ret_string, f_escape}, ! {"eval", 1, 1, FEARG_1, NULL, ! ret_any, f_eval}, ! {"eventhandler", 0, 0, 0, NULL, ! ret_number, f_eventhandler}, ! {"executable", 1, 1, FEARG_1, NULL, ! ret_number, f_executable}, ! {"execute", 1, 2, FEARG_1, NULL, ! ret_string, f_execute}, ! {"exepath", 1, 1, FEARG_1, NULL, ! ret_string, f_exepath}, ! {"exists", 1, 1, FEARG_1, NULL, ! ret_number, f_exists}, ! {"exp", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_exp)}, ! {"expand", 1, 3, FEARG_1, NULL, ! ret_any, f_expand}, ! {"expandcmd", 1, 1, FEARG_1, NULL, ! ret_string, f_expandcmd}, ! {"extend", 2, 3, FEARG_1, NULL, ! ret_first_arg, f_extend}, ! {"feedkeys", 1, 2, FEARG_1, NULL, ! ret_void, f_feedkeys}, ! {"file_readable", 1, 1, FEARG_1, NULL, ! ret_number, f_filereadable}, // obsolete ! {"filereadable", 1, 1, FEARG_1, NULL, ! ret_number, f_filereadable}, ! {"filewritable", 1, 1, FEARG_1, NULL, ! ret_number, f_filewritable}, ! {"filter", 2, 2, FEARG_1, NULL, ! ret_first_arg, f_filter}, ! {"finddir", 1, 3, FEARG_1, NULL, ! ret_string, f_finddir}, ! {"findfile", 1, 3, FEARG_1, NULL, ! ret_string, f_findfile}, ! {"flatten", 1, 2, FEARG_1, NULL, ! ret_list_any, f_flatten}, ! {"float2nr", 1, 1, FEARG_1, NULL, ! ret_number, FLOAT_FUNC(f_float2nr)}, ! {"floor", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_floor)}, ! {"fmod", 2, 2, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_fmod)}, ! {"fnameescape", 1, 1, FEARG_1, NULL, ! ret_string, f_fnameescape}, ! {"fnamemodify", 2, 2, FEARG_1, NULL, ! ret_string, f_fnamemodify}, ! {"foldclosed", 1, 1, FEARG_1, NULL, ! ret_number, f_foldclosed}, ! {"foldclosedend", 1, 1, FEARG_1, NULL, ! ret_number, f_foldclosedend}, ! {"foldlevel", 1, 1, FEARG_1, NULL, ! ret_number, f_foldlevel}, ! {"foldtext", 0, 0, 0, NULL, ! ret_string, f_foldtext}, ! {"foldtextresult", 1, 1, FEARG_1, NULL, ! ret_string, f_foldtextresult}, ! {"foreground", 0, 0, 0, NULL, ! ret_void, f_foreground}, ! {"funcref", 1, 3, FEARG_1, NULL, ! ret_func_any, f_funcref}, ! {"function", 1, 3, FEARG_1, NULL, ! ret_f_function, f_function}, ! {"garbagecollect", 0, 1, 0, NULL, ! ret_void, f_garbagecollect}, ! {"get", 2, 3, FEARG_1, NULL, ! ret_any, f_get}, ! {"getbufinfo", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, f_getbufinfo}, ! {"getbufline", 2, 3, FEARG_1, NULL, ! ret_list_string, f_getbufline}, ! {"getbufvar", 2, 3, FEARG_1, NULL, ! ret_any, f_getbufvar}, ! {"getchangelist", 0, 1, FEARG_1, NULL, ! ret_list_any, f_getchangelist}, ! {"getchar", 0, 1, 0, NULL, ! ret_number, f_getchar}, ! {"getcharmod", 0, 0, 0, NULL, ! ret_number, f_getcharmod}, ! {"getcharsearch", 0, 0, 0, NULL, ! ret_dict_any, f_getcharsearch}, ! {"getcmdline", 0, 0, 0, NULL, ! ret_string, f_getcmdline}, ! {"getcmdpos", 0, 0, 0, NULL, ! ret_number, f_getcmdpos}, ! {"getcmdtype", 0, 0, 0, NULL, ! ret_string, f_getcmdtype}, ! {"getcmdwintype", 0, 0, 0, NULL, ! ret_string, f_getcmdwintype}, ! {"getcompletion", 2, 3, FEARG_1, NULL, ! ret_list_string, f_getcompletion}, ! {"getcurpos", 0, 1, FEARG_1, NULL, ! ret_list_number, f_getcurpos}, ! {"getcwd", 0, 2, FEARG_1, NULL, ! ret_string, f_getcwd}, ! {"getenv", 1, 1, FEARG_1, NULL, ! ret_string, f_getenv}, ! {"getfontname", 0, 1, 0, NULL, ! ret_string, f_getfontname}, ! {"getfperm", 1, 1, FEARG_1, NULL, ! ret_string, f_getfperm}, ! {"getfsize", 1, 1, FEARG_1, NULL, ! ret_number, f_getfsize}, ! {"getftime", 1, 1, FEARG_1, NULL, ! ret_number, f_getftime}, ! {"getftype", 1, 1, FEARG_1, NULL, ! ret_string, f_getftype}, ! {"getimstatus", 0, 0, 0, NULL, ! ret_number, f_getimstatus}, ! {"getjumplist", 0, 2, FEARG_1, NULL, ! ret_list_any, f_getjumplist}, ! {"getline", 1, 2, FEARG_1, NULL, ! ret_f_getline, f_getline}, ! {"getloclist", 1, 2, 0, NULL, ! ret_list_or_dict_1, f_getloclist}, ! {"getmarklist", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, f_getmarklist}, ! {"getmatches", 0, 1, 0, NULL, ! ret_list_dict_any, f_getmatches}, ! {"getmousepos", 0, 0, 0, NULL, ! ret_dict_number, f_getmousepos}, ! {"getpid", 0, 0, 0, NULL, ! ret_number, f_getpid}, ! {"getpos", 1, 1, FEARG_1, NULL, ! ret_list_number, f_getpos}, ! {"getqflist", 0, 1, 0, NULL, ! ret_list_or_dict_0, f_getqflist}, ! {"getreg", 0, 3, FEARG_1, NULL, ! ret_getreg, f_getreg}, ! {"getreginfo", 0, 1, FEARG_1, NULL, ! ret_dict_any, f_getreginfo}, ! {"getregtype", 0, 1, FEARG_1, NULL, ! ret_string, f_getregtype}, ! {"gettabinfo", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, f_gettabinfo}, ! {"gettabvar", 2, 3, FEARG_1, NULL, ! ret_any, f_gettabvar}, ! {"gettabwinvar", 3, 4, FEARG_1, NULL, ! ret_any, f_gettabwinvar}, ! {"gettagstack", 0, 1, FEARG_1, NULL, ! ret_dict_any, f_gettagstack}, ! {"gettext", 1, 1, FEARG_1, NULL, ! ret_string, f_gettext}, ! {"getwininfo", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, f_getwininfo}, ! {"getwinpos", 0, 1, FEARG_1, NULL, ! ret_list_number, f_getwinpos}, ! {"getwinposx", 0, 0, 0, NULL, ! ret_number, f_getwinposx}, ! {"getwinposy", 0, 0, 0, NULL, ! ret_number, f_getwinposy}, ! {"getwinvar", 2, 3, FEARG_1, NULL, ! ret_any, f_getwinvar}, ! {"glob", 1, 4, FEARG_1, NULL, ! ret_any, f_glob}, ! {"glob2regpat", 1, 1, FEARG_1, NULL, ! ret_string, f_glob2regpat}, ! {"globpath", 2, 5, FEARG_2, NULL, ! ret_any, f_globpath}, ! {"has", 1, 2, 0, NULL, ! ret_number, f_has}, ! {"has_key", 2, 2, FEARG_1, NULL, ! ret_number, f_has_key}, ! {"haslocaldir", 0, 2, FEARG_1, NULL, ! ret_number, f_haslocaldir}, ! {"hasmapto", 1, 3, FEARG_1, NULL, ! ret_number, f_hasmapto}, ! {"highlightID", 1, 1, FEARG_1, NULL, ! ret_number, f_hlID}, // obsolete ! {"highlight_exists",1, 1, FEARG_1, NULL, ! ret_number, f_hlexists}, // obsolete ! {"histadd", 2, 2, FEARG_2, NULL, ! ret_number, f_histadd}, ! {"histdel", 1, 2, FEARG_1, NULL, ! ret_number, f_histdel}, ! {"histget", 1, 2, FEARG_1, NULL, ! ret_string, f_histget}, ! {"histnr", 1, 1, FEARG_1, NULL, ! ret_number, f_histnr}, ! {"hlID", 1, 1, FEARG_1, NULL, ! ret_number, f_hlID}, ! {"hlexists", 1, 1, FEARG_1, NULL, ! ret_number, f_hlexists}, ! {"hostname", 0, 0, 0, NULL, ! ret_string, f_hostname}, ! {"iconv", 3, 3, FEARG_1, NULL, ! ret_string, f_iconv}, ! {"indent", 1, 1, FEARG_1, NULL, ! ret_number, f_indent}, ! {"index", 2, 4, FEARG_1, NULL, ! ret_number, f_index}, ! {"input", 1, 3, FEARG_1, NULL, ! ret_string, f_input}, ! {"inputdialog", 1, 3, FEARG_1, NULL, ! ret_string, f_inputdialog}, ! {"inputlist", 1, 1, FEARG_1, NULL, ! ret_number, f_inputlist}, ! {"inputrestore", 0, 0, 0, NULL, ! ret_number, f_inputrestore}, ! {"inputsave", 0, 0, 0, NULL, ! ret_number, f_inputsave}, ! {"inputsecret", 1, 2, FEARG_1, NULL, ! ret_string, f_inputsecret}, ! {"insert", 2, 3, FEARG_1, NULL, ! ret_first_arg, f_insert}, ! {"interrupt", 0, 0, 0, NULL, ! ret_void, f_interrupt}, ! {"invert", 1, 1, FEARG_1, NULL, ! ret_number, f_invert}, ! {"isdirectory", 1, 1, FEARG_1, NULL, ! ret_number, f_isdirectory}, ! {"isinf", 1, 1, FEARG_1, NULL, ! ret_number, MATH_FUNC(f_isinf)}, ! {"islocked", 1, 1, FEARG_1, NULL, ! ret_number, f_islocked}, ! {"isnan", 1, 1, FEARG_1, NULL, ! ret_number, MATH_FUNC(f_isnan)}, ! {"items", 1, 1, FEARG_1, NULL, ! ret_list_any, f_items}, ! {"job_getchannel", 1, 1, FEARG_1, NULL, ! ret_channel, JOB_FUNC(f_job_getchannel)}, ! {"job_info", 0, 1, FEARG_1, NULL, ! ret_dict_any, JOB_FUNC(f_job_info)}, ! {"job_setoptions", 2, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_job_setoptions)}, ! {"job_start", 1, 2, FEARG_1, NULL, ! ret_job, JOB_FUNC(f_job_start)}, ! {"job_status", 1, 1, FEARG_1, NULL, ! ret_string, JOB_FUNC(f_job_status)}, ! {"job_stop", 1, 2, FEARG_1, NULL, ! ret_number, JOB_FUNC(f_job_stop)}, ! {"join", 1, 2, FEARG_1, NULL, ! ret_string, f_join}, ! {"js_decode", 1, 1, FEARG_1, NULL, ! ret_any, f_js_decode}, ! {"js_encode", 1, 1, FEARG_1, NULL, ! ret_string, f_js_encode}, ! {"json_decode", 1, 1, FEARG_1, NULL, ! ret_any, f_json_decode}, ! {"json_encode", 1, 1, FEARG_1, NULL, ! ret_string, f_json_encode}, ! {"keys", 1, 1, FEARG_1, NULL, ! ret_list_string, f_keys}, ! {"last_buffer_nr", 0, 0, 0, NULL, ! ret_number, f_last_buffer_nr}, // obsolete ! {"len", 1, 1, FEARG_1, NULL, ! ret_number, f_len}, ! {"libcall", 3, 3, FEARG_3, NULL, ! ret_string, f_libcall}, ! {"libcallnr", 3, 3, FEARG_3, NULL, ! ret_number, f_libcallnr}, ! {"line", 1, 2, FEARG_1, NULL, ! ret_number, f_line}, ! {"line2byte", 1, 1, FEARG_1, NULL, ! ret_number, f_line2byte}, ! {"lispindent", 1, 1, FEARG_1, NULL, ! ret_number, f_lispindent}, ! {"list2str", 1, 2, FEARG_1, NULL, ! ret_string, f_list2str}, ! {"listener_add", 1, 2, FEARG_2, NULL, ! ret_number, f_listener_add}, ! {"listener_flush", 0, 1, FEARG_1, NULL, ! ret_void, f_listener_flush}, ! {"listener_remove", 1, 1, FEARG_1, NULL, ! ret_number, f_listener_remove}, ! {"localtime", 0, 0, 0, NULL, ! ret_number, f_localtime}, ! {"log", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_log)}, ! {"log10", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_log10)}, ! {"luaeval", 1, 2, FEARG_1, NULL, ! ret_any, #ifdef FEAT_LUA f_luaeval #else NULL #endif }, ! {"map", 2, 2, FEARG_1, NULL, ! ret_any, f_map}, ! {"maparg", 1, 4, FEARG_1, NULL, ! ret_maparg, f_maparg}, ! {"mapcheck", 1, 3, FEARG_1, NULL, ! ret_string, f_mapcheck}, ! {"mapset", 3, 3, FEARG_1, NULL, ! ret_void, f_mapset}, ! {"match", 2, 4, FEARG_1, NULL, ! ret_any, f_match}, ! {"matchadd", 2, 5, FEARG_1, NULL, ! ret_number, f_matchadd}, ! {"matchaddpos", 2, 5, FEARG_1, NULL, ! ret_number, f_matchaddpos}, ! {"matcharg", 1, 1, FEARG_1, NULL, ! ret_list_string, f_matcharg}, ! {"matchdelete", 1, 2, FEARG_1, NULL, ! ret_number, f_matchdelete}, ! {"matchend", 2, 4, FEARG_1, NULL, ! ret_number, f_matchend}, ! {"matchfuzzy", 2, 3, FEARG_1, NULL, ! ret_list_string, f_matchfuzzy}, ! {"matchfuzzypos", 2, 3, FEARG_1, NULL, ! ret_list_any, f_matchfuzzypos}, ! {"matchlist", 2, 4, FEARG_1, NULL, ! ret_list_string, f_matchlist}, ! {"matchstr", 2, 4, FEARG_1, NULL, ! ret_string, f_matchstr}, ! {"matchstrpos", 2, 4, FEARG_1, NULL, ! ret_list_any, f_matchstrpos}, ! {"max", 1, 1, FEARG_1, NULL, ! ret_any, f_max}, ! {"menu_info", 1, 2, FEARG_1, NULL, ! ret_dict_any, #ifdef FEAT_MENU f_menu_info #else NULL #endif }, ! {"min", 1, 1, FEARG_1, NULL, ! ret_any, f_min}, ! {"mkdir", 1, 3, FEARG_1, NULL, ! ret_number, f_mkdir}, ! {"mode", 0, 1, FEARG_1, NULL, ! ret_string, f_mode}, ! {"mzeval", 1, 1, FEARG_1, NULL, ! ret_any, #ifdef FEAT_MZSCHEME f_mzeval #else NULL #endif }, ! {"nextnonblank", 1, 1, FEARG_1, NULL, ! ret_number, f_nextnonblank}, ! {"nr2char", 1, 2, FEARG_1, NULL, ! ret_string, f_nr2char}, ! {"or", 2, 2, FEARG_1, NULL, ! ret_number, f_or}, ! {"pathshorten", 1, 2, FEARG_1, NULL, ! ret_string, f_pathshorten}, ! {"perleval", 1, 1, FEARG_1, NULL, ! ret_any, #ifdef FEAT_PERL f_perleval #else NULL #endif }, ! {"popup_atcursor", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_atcursor)}, ! {"popup_beval", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_beval)}, ! {"popup_clear", 0, 1, 0, NULL, ! ret_void, PROP_FUNC(f_popup_clear)}, ! {"popup_close", 1, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_close)}, ! {"popup_create", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_create)}, ! {"popup_dialog", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_dialog)}, ! {"popup_filter_menu", 2, 2, 0, NULL, ! ret_bool, PROP_FUNC(f_popup_filter_menu)}, ! {"popup_filter_yesno", 2, 2, 0, NULL, ! ret_bool, PROP_FUNC(f_popup_filter_yesno)}, ! {"popup_findinfo", 0, 0, 0, NULL, ! ret_number, PROP_FUNC(f_popup_findinfo)}, ! {"popup_findpreview", 0, 0, 0, NULL, ! ret_number, PROP_FUNC(f_popup_findpreview)}, ! {"popup_getoptions", 1, 1, FEARG_1, NULL, ! ret_dict_any, PROP_FUNC(f_popup_getoptions)}, ! {"popup_getpos", 1, 1, FEARG_1, NULL, ! ret_dict_any, PROP_FUNC(f_popup_getpos)}, ! {"popup_hide", 1, 1, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_hide)}, ! {"popup_list", 0, 0, 0, NULL, ! ret_list_number, PROP_FUNC(f_popup_list)}, ! {"popup_locate", 2, 2, 0, NULL, ! ret_number, PROP_FUNC(f_popup_locate)}, ! {"popup_menu", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_menu)}, ! {"popup_move", 2, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_move)}, ! {"popup_notification", 2, 2, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_popup_notification)}, ! {"popup_setoptions", 2, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_setoptions)}, ! {"popup_settext", 2, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_settext)}, ! {"popup_show", 1, 1, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_popup_show)}, ! {"pow", 2, 2, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_pow)}, ! {"prevnonblank", 1, 1, FEARG_1, NULL, ! ret_number, f_prevnonblank}, ! {"printf", 1, 19, FEARG_2, NULL, ! ret_string, f_printf}, ! {"prompt_getprompt", 1, 1, FEARG_1, NULL, ! ret_string, JOB_FUNC(f_prompt_getprompt)}, ! {"prompt_setcallback", 2, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_prompt_setcallback)}, ! {"prompt_setinterrupt", 2, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_prompt_setinterrupt)}, ! {"prompt_setprompt", 2, 2, FEARG_1, NULL, ! ret_void, JOB_FUNC(f_prompt_setprompt)}, ! {"prop_add", 3, 3, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_prop_add)}, ! {"prop_clear", 1, 3, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_prop_clear)}, ! {"prop_find", 1, 2, FEARG_1, NULL, ! ret_dict_any, PROP_FUNC(f_prop_find)}, ! {"prop_list", 1, 2, FEARG_1, NULL, ! ret_list_dict_any, PROP_FUNC(f_prop_list)}, ! {"prop_remove", 1, 3, FEARG_1, NULL, ! ret_number, PROP_FUNC(f_prop_remove)}, ! {"prop_type_add", 2, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_prop_type_add)}, ! {"prop_type_change", 2, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_prop_type_change)}, ! {"prop_type_delete", 1, 2, FEARG_1, NULL, ! ret_void, PROP_FUNC(f_prop_type_delete)}, ! {"prop_type_get", 1, 2, FEARG_1, NULL, ! ret_dict_any, PROP_FUNC(f_prop_type_get)}, ! {"prop_type_list", 0, 1, FEARG_1, NULL, ! ret_list_string, PROP_FUNC(f_prop_type_list)}, ! {"pum_getpos", 0, 0, 0, NULL, ! ret_dict_number, f_pum_getpos}, ! {"pumvisible", 0, 0, 0, NULL, ! ret_number, f_pumvisible}, ! {"py3eval", 1, 1, FEARG_1, NULL, ! ret_any, #ifdef FEAT_PYTHON3 f_py3eval #else NULL #endif }, ! {"pyeval", 1, 1, FEARG_1, NULL, ! ret_any, #ifdef FEAT_PYTHON f_pyeval #else NULL #endif }, ! {"pyxeval", 1, 1, FEARG_1, NULL, ! ret_any, #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) f_pyxeval #else NULL #endif }, ! {"rand", 0, 1, FEARG_1, NULL, ! ret_number, f_rand}, ! {"range", 1, 3, FEARG_1, NULL, ! ret_list_number, f_range}, ! {"readdir", 1, 3, FEARG_1, NULL, ! ret_list_string, f_readdir}, ! {"readdirex", 1, 3, FEARG_1, NULL, ! ret_list_dict_any, f_readdirex}, ! {"readfile", 1, 3, FEARG_1, NULL, ! ret_any, f_readfile}, ! {"reduce", 2, 3, FEARG_1, NULL, ! ret_any, f_reduce}, ! {"reg_executing", 0, 0, 0, NULL, ! ret_string, f_reg_executing}, ! {"reg_recording", 0, 0, 0, NULL, ! ret_string, f_reg_recording}, ! {"reltime", 0, 2, FEARG_1, NULL, ! ret_list_any, f_reltime}, ! {"reltimefloat", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_reltimefloat)}, ! {"reltimestr", 1, 1, FEARG_1, NULL, ! ret_string, f_reltimestr}, ! {"remote_expr", 2, 4, FEARG_1, NULL, ! ret_string, f_remote_expr}, ! {"remote_foreground", 1, 1, FEARG_1, NULL, ! ret_string, f_remote_foreground}, ! {"remote_peek", 1, 2, FEARG_1, NULL, ! ret_number, f_remote_peek}, ! {"remote_read", 1, 2, FEARG_1, NULL, ! ret_string, f_remote_read}, ! {"remote_send", 2, 3, FEARG_1, NULL, ! ret_string, f_remote_send}, ! {"remote_startserver", 1, 1, FEARG_1, NULL, ! ret_void, f_remote_startserver}, ! {"remove", 2, 3, FEARG_1, NULL, ! ret_remove, f_remove}, ! {"rename", 2, 2, FEARG_1, NULL, ! ret_number, f_rename}, ! {"repeat", 2, 2, FEARG_1, NULL, ! ret_first_arg, f_repeat}, ! {"resolve", 1, 1, FEARG_1, NULL, ! ret_string, f_resolve}, ! {"reverse", 1, 1, FEARG_1, NULL, ! ret_first_arg, f_reverse}, ! {"round", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_round)}, ! {"rubyeval", 1, 1, FEARG_1, NULL, ! ret_any, #ifdef FEAT_RUBY f_rubyeval #else NULL #endif }, ! {"screenattr", 2, 2, FEARG_1, NULL, ! ret_number, f_screenattr}, ! {"screenchar", 2, 2, FEARG_1, NULL, ! ret_number, f_screenchar}, ! {"screenchars", 2, 2, FEARG_1, NULL, ! ret_list_number, f_screenchars}, ! {"screencol", 0, 0, 0, NULL, ! ret_number, f_screencol}, ! {"screenpos", 3, 3, FEARG_1, NULL, ! ret_dict_number, f_screenpos}, ! {"screenrow", 0, 0, 0, NULL, ! ret_number, f_screenrow}, ! {"screenstring", 2, 2, FEARG_1, NULL, ! ret_string, f_screenstring}, ! {"search", 1, 5, FEARG_1, NULL, ! ret_number, f_search}, ! {"searchcount", 0, 1, FEARG_1, NULL, ! ret_dict_any, f_searchcount}, ! {"searchdecl", 1, 3, FEARG_1, NULL, ! ret_number, f_searchdecl}, ! {"searchpair", 3, 7, 0, NULL, ! ret_number, f_searchpair}, ! {"searchpairpos", 3, 7, 0, NULL, ! ret_list_number, f_searchpairpos}, ! {"searchpos", 1, 5, FEARG_1, NULL, ! ret_list_number, f_searchpos}, ! {"server2client", 2, 2, FEARG_1, NULL, ! ret_number, f_server2client}, ! {"serverlist", 0, 0, 0, NULL, ! ret_string, f_serverlist}, ! {"setbufline", 3, 3, FEARG_3, NULL, ! ret_number, f_setbufline}, ! {"setbufvar", 3, 3, FEARG_3, NULL, ! ret_void, f_setbufvar}, ! {"setcellwidths", 1, 1, FEARG_1, NULL, ! ret_void, f_setcellwidths}, ! {"setcharsearch", 1, 1, FEARG_1, NULL, ! ret_void, f_setcharsearch}, ! {"setcmdpos", 1, 1, FEARG_1, NULL, ! ret_number, f_setcmdpos}, ! {"setenv", 2, 2, FEARG_2, NULL, ! ret_void, f_setenv}, ! {"setfperm", 2, 2, FEARG_1, NULL, ! ret_number, f_setfperm}, ! {"setline", 2, 2, FEARG_2, NULL, ! ret_number, f_setline}, ! {"setloclist", 2, 4, FEARG_2, NULL, ! ret_number, f_setloclist}, ! {"setmatches", 1, 2, FEARG_1, NULL, ! ret_number, f_setmatches}, ! {"setpos", 2, 2, FEARG_2, NULL, ! ret_number, f_setpos}, ! {"setqflist", 1, 3, FEARG_1, NULL, ! ret_number, f_setqflist}, ! {"setreg", 2, 3, FEARG_2, NULL, ! ret_number, f_setreg}, ! {"settabvar", 3, 3, FEARG_3, NULL, ! ret_void, f_settabvar}, ! {"settabwinvar", 4, 4, FEARG_4, NULL, ! ret_void, f_settabwinvar}, ! {"settagstack", 2, 3, FEARG_2, NULL, ! ret_number, f_settagstack}, ! {"setwinvar", 3, 3, FEARG_3, NULL, ! ret_void, f_setwinvar}, ! {"sha256", 1, 1, FEARG_1, NULL, ! ret_string, #ifdef FEAT_CRYPT f_sha256 #else NULL #endif }, ! {"shellescape", 1, 2, FEARG_1, NULL, ! ret_string, f_shellescape}, ! {"shiftwidth", 0, 1, FEARG_1, NULL, ! ret_number, f_shiftwidth}, ! {"sign_define", 1, 2, FEARG_1, NULL, ! ret_any, SIGN_FUNC(f_sign_define)}, ! {"sign_getdefined", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)}, ! {"sign_getplaced", 0, 2, FEARG_1, NULL, ! ret_list_dict_any, SIGN_FUNC(f_sign_getplaced)}, ! {"sign_jump", 3, 3, FEARG_1, NULL, ! ret_number, SIGN_FUNC(f_sign_jump)}, ! {"sign_place", 4, 5, FEARG_1, NULL, ! ret_number, SIGN_FUNC(f_sign_place)}, ! {"sign_placelist", 1, 1, FEARG_1, NULL, ! ret_list_number, SIGN_FUNC(f_sign_placelist)}, ! {"sign_undefine", 0, 1, FEARG_1, NULL, ! ret_number, SIGN_FUNC(f_sign_undefine)}, ! {"sign_unplace", 1, 2, FEARG_1, NULL, ! ret_number, SIGN_FUNC(f_sign_unplace)}, ! {"sign_unplacelist", 1, 2, FEARG_1, NULL, ! ret_list_number, SIGN_FUNC(f_sign_unplacelist)}, ! {"simplify", 1, 1, FEARG_1, NULL, ! ret_string, f_simplify}, ! {"sin", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_sin)}, ! {"sinh", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_sinh)}, ! {"sort", 1, 3, FEARG_1, NULL, ! ret_first_arg, f_sort}, ! {"sound_clear", 0, 0, 0, NULL, ! ret_void, SOUND_FUNC(f_sound_clear)}, ! {"sound_playevent", 1, 2, FEARG_1, NULL, ! ret_number, SOUND_FUNC(f_sound_playevent)}, ! {"sound_playfile", 1, 2, FEARG_1, NULL, ! ret_number, SOUND_FUNC(f_sound_playfile)}, ! {"sound_stop", 1, 1, FEARG_1, NULL, ! ret_void, SOUND_FUNC(f_sound_stop)}, ! {"soundfold", 1, 1, FEARG_1, NULL, ! ret_string, f_soundfold}, ! {"spellbadword", 0, 1, FEARG_1, NULL, ! ret_list_string, f_spellbadword}, ! {"spellsuggest", 1, 3, FEARG_1, NULL, ! ret_list_string, f_spellsuggest}, ! {"split", 1, 3, FEARG_1, NULL, ! ret_list_string, f_split}, ! {"sqrt", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_sqrt)}, ! {"srand", 0, 1, FEARG_1, NULL, ! ret_list_number, f_srand}, ! {"state", 0, 1, FEARG_1, NULL, ! ret_string, f_state}, ! {"str2float", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_str2float)}, ! {"str2list", 1, 2, FEARG_1, NULL, ! ret_list_number, f_str2list}, ! {"str2nr", 1, 3, FEARG_1, NULL, ! ret_number, f_str2nr}, ! {"strcharpart", 2, 3, FEARG_1, NULL, ! ret_string, f_strcharpart}, ! {"strchars", 1, 2, FEARG_1, NULL, ! ret_number, f_strchars}, ! {"strdisplaywidth", 1, 2, FEARG_1, NULL, ! ret_number, f_strdisplaywidth}, ! {"strftime", 1, 2, FEARG_1, NULL, ! ret_string, #ifdef HAVE_STRFTIME f_strftime #else NULL #endif }, ! {"strgetchar", 2, 2, FEARG_1, NULL, ! ret_number, f_strgetchar}, ! {"stridx", 2, 3, FEARG_1, NULL, ! ret_number, f_stridx}, ! {"string", 1, 1, FEARG_1, NULL, ! ret_string, f_string}, ! {"strlen", 1, 1, FEARG_1, NULL, ! ret_number, f_strlen}, ! {"strpart", 2, 4, FEARG_1, NULL, ! ret_string, f_strpart}, ! {"strptime", 2, 2, FEARG_1, NULL, ! ret_number, #ifdef HAVE_STRPTIME f_strptime #else NULL #endif }, ! {"strridx", 2, 3, FEARG_1, NULL, ! ret_number, f_strridx}, ! {"strtrans", 1, 1, FEARG_1, NULL, ! ret_string, f_strtrans}, ! {"strwidth", 1, 1, FEARG_1, NULL, ! ret_number, f_strwidth}, ! {"submatch", 1, 2, FEARG_1, NULL, ! ret_string, f_submatch}, ! {"substitute", 4, 4, FEARG_1, NULL, ! ret_string, f_substitute}, ! {"swapinfo", 1, 1, FEARG_1, NULL, ! ret_dict_any, f_swapinfo}, ! {"swapname", 1, 1, FEARG_1, NULL, ! ret_string, f_swapname}, ! {"synID", 3, 3, 0, NULL, ! ret_number, f_synID}, ! {"synIDattr", 2, 3, FEARG_1, NULL, ! ret_string, f_synIDattr}, ! {"synIDtrans", 1, 1, FEARG_1, NULL, ! ret_number, f_synIDtrans}, ! {"synconcealed", 2, 2, 0, NULL, ! ret_list_any, f_synconcealed}, ! {"synstack", 2, 2, 0, NULL, ! ret_list_number, f_synstack}, ! {"system", 1, 2, FEARG_1, NULL, ! ret_string, f_system}, ! {"systemlist", 1, 2, FEARG_1, NULL, ! ret_list_string, f_systemlist}, ! {"tabpagebuflist", 0, 1, FEARG_1, NULL, ! ret_list_number, f_tabpagebuflist}, ! {"tabpagenr", 0, 1, 0, NULL, ! ret_number, f_tabpagenr}, ! {"tabpagewinnr", 1, 2, FEARG_1, NULL, ! ret_number, f_tabpagewinnr}, ! {"tagfiles", 0, 0, 0, NULL, ! ret_list_string, f_tagfiles}, ! {"taglist", 1, 2, FEARG_1, NULL, ! ret_list_dict_any, f_taglist}, ! {"tan", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_tan)}, ! {"tanh", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_tanh)}, ! {"tempname", 0, 0, 0, NULL, ! ret_string, f_tempname}, ! {"term_dumpdiff", 2, 3, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_dumpdiff)}, ! {"term_dumpload", 1, 2, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_dumpload)}, ! {"term_dumpwrite", 2, 3, FEARG_2, NULL, ! ret_void, TERM_FUNC(f_term_dumpwrite)}, ! {"term_getaltscreen", 1, 1, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_getaltscreen)}, ! {"term_getansicolors", 1, 1, FEARG_1, NULL, ! ret_list_string, #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) f_term_getansicolors #else NULL #endif }, ! {"term_getattr", 2, 2, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_getattr)}, ! {"term_getcursor", 1, 1, FEARG_1, NULL, ! ret_list_any, TERM_FUNC(f_term_getcursor)}, ! {"term_getjob", 1, 1, FEARG_1, NULL, ! ret_job, TERM_FUNC(f_term_getjob)}, ! {"term_getline", 2, 2, FEARG_1, NULL, ! ret_string, TERM_FUNC(f_term_getline)}, ! {"term_getscrolled", 1, 1, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_getscrolled)}, ! {"term_getsize", 1, 1, FEARG_1, NULL, ! ret_list_number, TERM_FUNC(f_term_getsize)}, ! {"term_getstatus", 1, 1, FEARG_1, NULL, ! ret_string, TERM_FUNC(f_term_getstatus)}, ! {"term_gettitle", 1, 1, FEARG_1, NULL, ! ret_string, TERM_FUNC(f_term_gettitle)}, ! {"term_gettty", 1, 2, FEARG_1, NULL, ! ret_string, TERM_FUNC(f_term_gettty)}, ! {"term_list", 0, 0, 0, NULL, ! ret_list_number, TERM_FUNC(f_term_list)}, ! {"term_scrape", 2, 2, FEARG_1, NULL, ! ret_list_dict_any, TERM_FUNC(f_term_scrape)}, ! {"term_sendkeys", 2, 2, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_sendkeys)}, ! {"term_setansicolors", 2, 2, FEARG_1, NULL, ! ret_void, #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) f_term_setansicolors #else NULL #endif }, ! {"term_setapi", 2, 2, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_setapi)}, ! {"term_setkill", 2, 2, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_setkill)}, ! {"term_setrestore", 2, 2, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_setrestore)}, ! {"term_setsize", 3, 3, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_setsize)}, ! {"term_start", 1, 2, FEARG_1, NULL, ! ret_number, TERM_FUNC(f_term_start)}, ! {"term_wait", 1, 2, FEARG_1, NULL, ! ret_void, TERM_FUNC(f_term_wait)}, ! {"terminalprops", 0, 0, 0, NULL, ! ret_dict_string, f_terminalprops}, ! {"test_alloc_fail", 3, 3, FEARG_1, NULL, ! ret_void, f_test_alloc_fail}, ! {"test_autochdir", 0, 0, 0, NULL, ! ret_void, f_test_autochdir}, ! {"test_feedinput", 1, 1, FEARG_1, NULL, ! ret_void, f_test_feedinput}, ! {"test_garbagecollect_now", 0, 0, 0, NULL, ! ret_void, f_test_garbagecollect_now}, ! {"test_garbagecollect_soon", 0, 0, 0, NULL, ! ret_void, f_test_garbagecollect_soon}, ! {"test_getvalue", 1, 1, FEARG_1, NULL, ! ret_number, f_test_getvalue}, ! {"test_ignore_error", 1, 1, FEARG_1, NULL, ! ret_void, f_test_ignore_error}, ! {"test_null_blob", 0, 0, 0, NULL, ! ret_blob, f_test_null_blob}, ! {"test_null_channel", 0, 0, 0, NULL, ! ret_channel, JOB_FUNC(f_test_null_channel)}, ! {"test_null_dict", 0, 0, 0, NULL, ! ret_dict_any, f_test_null_dict}, ! {"test_null_function", 0, 0, 0, NULL, ! ret_func_any, f_test_null_function}, ! {"test_null_job", 0, 0, 0, NULL, ! ret_job, JOB_FUNC(f_test_null_job)}, ! {"test_null_list", 0, 0, 0, NULL, ! ret_list_any, f_test_null_list}, ! {"test_null_partial", 0, 0, 0, NULL, ! ret_func_any, f_test_null_partial}, ! {"test_null_string", 0, 0, 0, NULL, ! ret_string, f_test_null_string}, ! {"test_option_not_set", 1, 1, FEARG_1, NULL, ! ret_void, f_test_option_not_set}, ! {"test_override", 2, 2, FEARG_2, NULL, ! ret_void, f_test_override}, ! {"test_refcount", 1, 1, FEARG_1, NULL, ! ret_number, f_test_refcount}, ! {"test_scrollbar", 3, 3, FEARG_2, NULL, ! ret_void, #ifdef FEAT_GUI f_test_scrollbar #else NULL #endif }, ! {"test_setmouse", 2, 2, 0, NULL, ! ret_void, f_test_setmouse}, ! {"test_settime", 1, 1, FEARG_1, NULL, ! ret_void, f_test_settime}, ! {"test_srand_seed", 0, 1, FEARG_1, NULL, ! ret_void, f_test_srand_seed}, ! {"test_unknown", 0, 0, 0, NULL, ! ret_any, f_test_unknown}, ! {"test_void", 0, 0, 0, NULL, ! ret_void, f_test_void}, ! {"timer_info", 0, 1, FEARG_1, NULL, ! ret_list_dict_any, TIMER_FUNC(f_timer_info)}, ! {"timer_pause", 2, 2, FEARG_1, NULL, ! ret_void, TIMER_FUNC(f_timer_pause)}, ! {"timer_start", 2, 3, FEARG_1, NULL, ! ret_number, TIMER_FUNC(f_timer_start)}, ! {"timer_stop", 1, 1, FEARG_1, NULL, ! ret_void, TIMER_FUNC(f_timer_stop)}, ! {"timer_stopall", 0, 0, 0, NULL, ! ret_void, TIMER_FUNC(f_timer_stopall)}, ! {"tolower", 1, 1, FEARG_1, NULL, ! ret_string, f_tolower}, ! {"toupper", 1, 1, FEARG_1, NULL, ! ret_string, f_toupper}, ! {"tr", 3, 3, FEARG_1, NULL, ! ret_string, f_tr}, ! {"trim", 1, 3, FEARG_1, NULL, ! ret_string, f_trim}, ! {"trunc", 1, 1, FEARG_1, NULL, ! ret_float, FLOAT_FUNC(f_trunc)}, ! {"type", 1, 1, FEARG_1, NULL, ! ret_number, f_type}, ! {"undofile", 1, 1, FEARG_1, NULL, ! ret_string, f_undofile}, ! {"undotree", 0, 0, 0, NULL, ! ret_dict_any, f_undotree}, ! {"uniq", 1, 3, FEARG_1, NULL, ! ret_list_any, f_uniq}, ! {"values", 1, 1, FEARG_1, NULL, ! ret_list_any, f_values}, ! {"virtcol", 1, 1, FEARG_1, NULL, ! ret_number, f_virtcol}, ! {"visualmode", 0, 1, 0, NULL, ! ret_string, f_visualmode}, ! {"wildmenumode", 0, 0, 0, NULL, ! ret_number, f_wildmenumode}, ! {"win_execute", 2, 3, FEARG_2, NULL, ! ret_string, f_win_execute}, ! {"win_findbuf", 1, 1, FEARG_1, NULL, ! ret_list_number, f_win_findbuf}, ! {"win_getid", 0, 2, FEARG_1, NULL, ! ret_number, f_win_getid}, ! {"win_gettype", 0, 1, FEARG_1, NULL, ! ret_string, f_win_gettype}, ! {"win_gotoid", 1, 1, FEARG_1, NULL, ! ret_number, f_win_gotoid}, ! {"win_id2tabwin", 1, 1, FEARG_1, NULL, ! ret_list_number, f_win_id2tabwin}, ! {"win_id2win", 1, 1, FEARG_1, NULL, ! ret_number, f_win_id2win}, ! {"win_screenpos", 1, 1, FEARG_1, NULL, ! ret_list_number, f_win_screenpos}, ! {"win_splitmove", 2, 3, FEARG_1, NULL, ! ret_number, f_win_splitmove}, ! {"winbufnr", 1, 1, FEARG_1, NULL, ! ret_number, f_winbufnr}, ! {"wincol", 0, 0, 0, NULL, ! ret_number, f_wincol}, ! {"windowsversion", 0, 0, 0, NULL, ! ret_string, f_windowsversion}, ! {"winheight", 1, 1, FEARG_1, NULL, ! ret_number, f_winheight}, ! {"winlayout", 0, 1, FEARG_1, NULL, ! ret_list_any, f_winlayout}, ! {"winline", 0, 0, 0, NULL, ! ret_number, f_winline}, ! {"winnr", 0, 1, FEARG_1, NULL, ! ret_number, f_winnr}, ! {"winrestcmd", 0, 0, 0, NULL, ! ret_string, f_winrestcmd}, ! {"winrestview", 1, 1, FEARG_1, NULL, ! ret_void, f_winrestview}, ! {"winsaveview", 0, 0, 0, NULL, ! ret_dict_any, f_winsaveview}, ! {"winwidth", 1, 1, FEARG_1, NULL, ! ret_number, f_winwidth}, ! {"wordcount", 0, 0, 0, NULL, ! ret_dict_number, f_wordcount}, ! {"writefile", 2, 3, FEARG_1, NULL, ! ret_number, f_writefile}, ! {"xor", 2, 2, FEARG_1, NULL, ! ret_number, f_xor}, }; /* *************** *** 1216,1221 **** --- 1757,1789 ---- return global_functions[idx].f_name; } + /* + * Check the argument types for builting function "idx". + * Uses the list of types on the type stack: "types". + * Return FAIL and gives an error message when a type is wrong. + */ + int + internal_func_check_arg_types(type_T *types, int idx, int argcount) + { + argcheck_T *argchecks = global_functions[idx].f_argcheck; + int i; + + if (argchecks != NULL) + { + argcontext_T context; + + context.arg_count = argcount; + for (i = 0; i < argcount; ++i) + if (argchecks[i] != NULL) + { + context.arg_idx = i; + if (argchecks[i](types + i, &context) == FAIL) + return FAIL; + } + } + return OK; + } + type_T * internal_func_ret_type(int idx, int argcount, type_T **argtypes) { *** ../vim-8.2.1875/src/proto/evalfunc.pro 2020-05-30 17:05:57.032692393 +0200 --- src/proto/evalfunc.pro 2020-10-21 13:28:31.493944844 +0200 *************** *** 4,9 **** --- 4,10 ---- int find_internal_func(char_u *name); int has_internal_func(char_u *name); char *internal_func_name(int idx); + int internal_func_check_arg_types(type_T *types, int idx, int argcount); type_T *internal_func_ret_type(int idx, int argcount, type_T **argtypes); int check_internal_func(int idx, int argcount); int call_internal_func(char_u *name, int argcount, typval_T *argvars, typval_T *rettv); *** ../vim-8.2.1875/src/vim9compile.c 2020-10-19 21:45:03.747157645 +0200 --- src/vim9compile.c 2020-10-21 13:45:28.934229523 +0200 *************** *** 1460,1467 **** isn_T *isn; garray_T *stack = &cctx->ctx_type_stack; int argoff; ! type_T *argtypes[MAX_FUNC_ARGS]; ! int i; RETURN_OK_IF_SKIP(cctx); argoff = check_internal_func(func_idx, argcount); --- 1460,1466 ---- isn_T *isn; garray_T *stack = &cctx->ctx_type_stack; int argoff; ! type_T **argtypes; RETURN_OK_IF_SKIP(cctx); argoff = check_internal_func(func_idx, argcount); *************** *** 1476,1495 **** isn->isn_arg.shuffle.shfl_up = argoff - 1; } if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL) return FAIL; isn->isn_arg.bfunc.cbf_idx = func_idx; isn->isn_arg.bfunc.cbf_argcount = argcount; ! for (i = 0; i < argcount; ++i) ! argtypes[i] = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; ! ! stack->ga_len -= argcount; // drop the arguments if (ga_grow(stack, 1) == FAIL) return FAIL; ((type_T **)stack->ga_data)[stack->ga_len] = internal_func_ret_type(func_idx, argcount, argtypes); ! ++stack->ga_len; // add return value return OK; } --- 1475,1498 ---- isn->isn_arg.shuffle.shfl_up = argoff - 1; } + // Check the types of the arguments. + argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount; + if (argcount > 0 && internal_func_check_arg_types( + *argtypes, func_idx, argcount) == FAIL) + return FAIL; + if ((isn = generate_instr(cctx, ISN_BCALL)) == NULL) return FAIL; isn->isn_arg.bfunc.cbf_idx = func_idx; isn->isn_arg.bfunc.cbf_argcount = argcount; ! // Drop the argument types and push the return type. ! stack->ga_len -= argcount; if (ga_grow(stack, 1) == FAIL) return FAIL; ((type_T **)stack->ga_data)[stack->ga_len] = internal_func_ret_type(func_idx, argcount, argtypes); ! ++stack->ga_len; return OK; } *** ../vim-8.2.1875/src/testdir/test_vim9_func.vim 2020-10-19 20:45:32.376596657 +0200 --- src/testdir/test_vim9_func.vim 2020-10-21 14:08:39.540712521 +0200 *************** *** 459,470 **** CheckScriptFailure(lines, 'E1013: Argument 1: type mismatch') enddef - def Test_call_call() - var l = [3, 2, 1] - call('reverse', [l]) - l->assert_equal([1, 2, 3]) - enddef - let s:value = '' def FuncOneDefArg(opt = 'text') --- 459,464 ---- *************** *** 944,1009 **** delete('XVim9Func') enddef - " Test for internal functions returning different types - func Test_InternalFuncRetType() - let lines =<< trim END - def RetFloat(): float - return ceil(1.456) - enddef - - def RetListAny(): list - return items({'k': 'v'}) - enddef - - def RetListString(): list - return split('a:b:c', ':') - enddef - - def RetListDictAny(): list> - return getbufinfo() - enddef - - def RetDictNumber(): dict - return wordcount() - enddef - - def RetDictString(): dict - return environ() - enddef - END - call writefile(lines, 'Xscript') - source Xscript - - call RetFloat()->assert_equal(2.0) - call RetListAny()->assert_equal([['k', 'v']]) - call RetListString()->assert_equal(['a', 'b', 'c']) - call RetListDictAny()->assert_notequal([]) - call RetDictNumber()->assert_notequal({}) - call RetDictString()->assert_notequal({}) - call delete('Xscript') - endfunc - - " Test for passing too many or too few arguments to internal functions - func Test_internalfunc_arg_error() - let l =<< trim END - def! FArgErr(): float - return ceil(1.1, 2) - enddef - defcompile - END - call writefile(l, 'Xinvalidarg') - call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') - let l =<< trim END - def! FArgErr(): float - return ceil() - enddef - defcompile - END - call writefile(l, 'Xinvalidarg') - call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') - call delete('Xinvalidarg') - endfunc - let s:funcResult = 0 def FuncNoArgNoRet() --- 938,943 ---- *************** *** 1481,1617 **** CheckScriptSuccess(lines) enddef - def Test_sort_return_type() - var res: list - res = [1, 2, 3]->sort() - enddef - - def Test_sort_argument() - var res = ['b', 'a', 'c']->sort('i') - res->assert_equal(['a', 'b', 'c']) - enddef - - def Test_getqflist_return_type() - var l = getqflist() - l->assert_equal([]) - - var d = getqflist(#{items: 0}) - d->assert_equal(#{items: []}) - enddef - - def Test_getloclist_return_type() - var l = getloclist(1) - l->assert_equal([]) - - var d = getloclist(1, #{items: 0}) - d->assert_equal(#{items: []}) - enddef - - def Test_copy_return_type() - var l = copy([1, 2, 3]) - var res = 0 - for n in l - res += n - endfor - res->assert_equal(6) - - var dl = deepcopy([1, 2, 3]) - res = 0 - for n in dl - res += n - endfor - res->assert_equal(6) - - dl = deepcopy([1, 2, 3], true) - enddef - - def Test_extend_return_type() - var l = extend([1, 2], [3]) - var res = 0 - for n in l - res += n - endfor - res->assert_equal(6) - enddef - - def Test_garbagecollect() - garbagecollect(true) - enddef - - def Test_insert_return_type() - var l = insert([2, 1], 3) - var res = 0 - for n in l - res += n - endfor - res->assert_equal(6) - enddef - - def Test_keys_return_type() - const var: list = #{a: 1, b: 2}->keys() - var->assert_equal(['a', 'b']) - enddef - - def Test_reverse_return_type() - var l = reverse([1, 2, 3]) - var res = 0 - for n in l - res += n - endfor - res->assert_equal(6) - enddef - - def Test_remove_return_type() - var l = remove(#{one: [1, 2], two: [3, 4]}, 'one') - var res = 0 - for n in l - res += n - endfor - res->assert_equal(3) - enddef - - def Test_filter_return_type() - var l = filter([1, 2, 3], {-> 1}) - var res = 0 - for n in l - res += n - endfor - res->assert_equal(6) - enddef - - def Test_bufnr() - var buf = bufnr() - bufnr('%')->assert_equal(buf) - - buf = bufnr('Xdummy', true) - buf->assert_notequal(-1) - exe 'bwipe! ' .. buf - enddef - - def Test_col() - new - setline(1, 'asdf') - col([1, '$'])->assert_equal(5) - enddef - - def Test_char2nr() - char2nr('あ', true)->assert_equal(12354) - enddef - - def Test_getreg_return_type() - var s1: string = getreg('"') - var s2: string = getreg('"', 1) - var s3: list = getreg('"', 1, 1) - enddef - - def Wrong_dict_key_type(items: list): list - return filter(items, {_, val -> get({val: 1}, 'x')}) - enddef - - def Test_wrong_dict_key_type() - assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') - enddef - def Line_continuation_in_def(dir: string = ''): string var path: string = empty(dir) \ ? 'empty' --- 1415,1420 ---- *************** *** 1657,2002 **** call delete('XTest_silent_echo') endfunc - """"""" builtin functions that behave differently in Vim9 - - def Test_bufname() - split SomeFile - bufname('%')->assert_equal('SomeFile') - edit OtherFile - bufname('#')->assert_equal('SomeFile') - close - enddef - - def Test_bufwinid() - var origwin = win_getid() - below split SomeFile - var SomeFileID = win_getid() - below split OtherFile - below split SomeFile - bufwinid('SomeFile')->assert_equal(SomeFileID) - - win_gotoid(origwin) - only - bwipe SomeFile - bwipe OtherFile - enddef - - def Test_count() - count('ABC ABC ABC', 'b', true)->assert_equal(3) - count('ABC ABC ABC', 'b', false)->assert_equal(0) - enddef - - def Test_expand() - split SomeFile - expand('%', true, true)->assert_equal(['SomeFile']) - close - enddef - - def Test_getbufinfo() - var bufinfo = getbufinfo(bufnr()) - getbufinfo('%')->assert_equal(bufinfo) - - edit Xtestfile1 - hide edit Xtestfile2 - hide enew - getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) - ->len()->assert_equal(3) - bwipe Xtestfile1 Xtestfile2 - enddef - - def Test_getbufline() - e SomeFile - var buf = bufnr() - e # - var lines = ['aaa', 'bbb', 'ccc'] - setbufline(buf, 1, lines) - getbufline('#', 1, '$')->assert_equal(lines) - - bwipe! - enddef - - def Test_getchangelist() - new - setline(1, 'some text') - var changelist = bufnr()->getchangelist() - getchangelist('%')->assert_equal(changelist) - bwipe! - enddef - - def Test_getchar() - while getchar(0) - endwhile - getchar(true)->assert_equal(0) - enddef - - def Test_getcompletion() - set wildignore=*.vim,*~ - var l = getcompletion('run', 'file', true) - l->assert_equal([]) - set wildignore& - enddef - - def Test_getreg() - var lines = ['aaa', 'bbb', 'ccc'] - setreg('a', lines) - getreg('a', true, true)->assert_equal(lines) - enddef - - def Test_glob() - glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) - enddef - - def Test_globpath() - globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) - enddef - - def Test_has() - has('eval', true)->assert_equal(1) - enddef - - def Test_hasmapto() - hasmapto('foobar', 'i', true)->assert_equal(0) - iabbrev foo foobar - hasmapto('foobar', 'i', true)->assert_equal(1) - iunabbrev foo - enddef - - def Test_index() - index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) - enddef - - def Test_list2str_str2list_utf8() - var s = "\u3042\u3044" - var l = [0x3042, 0x3044] - str2list(s, true)->assert_equal(l) - list2str(l, true)->assert_equal(s) - enddef - - def Test_list_add() - var l: list # defaults to empty list - add(l, 9) - assert_equal([9], l) - - var lines =<< trim END - var l: list - add(l, "x") - END - CheckDefFailure(lines, 'E1012:', 2) - - lines =<< trim END - var l: list = test_null_list() - add(l, 123) - END - CheckDefExecFailure(lines, 'E1130:', 2) - enddef - - def Test_blob_add() - var b1: blob = 0z12 - add(b1, 0x34) - assert_equal(0z1234, b1) - - var b2: blob # defaults to empty blob - add(b2, 0x67) - assert_equal(0z67, b2) - - var lines =<< trim END - var b: blob - add(b, "x") - END - CheckDefFailure(lines, 'E1012:', 2) - - lines =<< trim END - var b: blob = test_null_blob() - add(b, 123) - END - CheckDefExecFailure(lines, 'E1131:', 2) - enddef - - def SID(): number - return expand('') - ->matchstr('\zs\d\+\ze_$') - ->str2nr() - enddef - - def Test_maparg() - var lnum = str2nr(expand('')) - map foo bar - maparg('foo', '', false, true)->assert_equal(#{ - lnum: lnum + 1, - script: 0, - mode: ' ', - silent: 0, - noremap: 0, - lhs: 'foo', - lhsraw: 'foo', - nowait: 0, - expr: 0, - sid: SID(), - rhs: 'bar', - buffer: 0}) - unmap foo - enddef - - def Test_mapcheck() - iabbrev foo foobar - mapcheck('foo', 'i', true)->assert_equal('foobar') - iunabbrev foo - enddef - - def Test_maparg_mapset() - nnoremap :echo "hit F3" - var mapsave = maparg('', 'n', false, true) - mapset('n', false, mapsave) - - nunmap - enddef - - def Test_nr2char() - nr2char(97, true)->assert_equal('a') - enddef - - def Test_readdir() - eval expand('sautest')->readdir({e -> e[0] !=# '.'}) - eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) - enddef - - def Test_search() - new - setline(1, ['foo', 'bar']) - var val = 0 - # skip expr returns boolean - search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) - :1 - search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) - # skip expr returns number, only 0 and 1 are accepted - :1 - search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) - :1 - search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) - assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') - assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') - enddef - - def Test_searchcount() - new - setline(1, "foo bar") - :/foo - searchcount(#{recompute: true}) - ->assert_equal(#{ - exact_match: 1, - current: 1, - total: 1, - maxcount: 99, - incomplete: 0}) - bwipe! - enddef - - def Test_searchdecl() - searchdecl('blah', true, true)->assert_equal(1) - enddef - - def Test_setbufvar() - setbufvar(bufnr('%'), '&syntax', 'vim') - &syntax->assert_equal('vim') - setbufvar(bufnr('%'), '&ts', 16) - &ts->assert_equal(16) - settabwinvar(1, 1, '&syntax', 'vam') - &syntax->assert_equal('vam') - settabwinvar(1, 1, '&ts', 15) - &ts->assert_equal(15) - setlocal ts=8 - - setbufvar('%', 'myvar', 123) - getbufvar('%', 'myvar')->assert_equal(123) - enddef - - def Test_setloclist() - var items = [#{filename: '/tmp/file', lnum: 1, valid: true}] - var what = #{items: items} - setqflist([], ' ', what) - setloclist(0, [], ' ', what) - enddef - - def Test_setreg() - setreg('a', ['aaa', 'bbb', 'ccc']) - var reginfo = getreginfo('a') - setreg('a', reginfo) - getreginfo('a')->assert_equal(reginfo) - enddef - - def Test_spellsuggest() - if !has('spell') - MissingFeature 'spell' - else - spellsuggest('marrch', 1, true)->assert_equal(['March']) - endif - enddef - - def Test_split() - split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) - enddef - - def Test_str2nr() - str2nr("1'000'000", 10, true)->assert_equal(1000000) - enddef - - def Test_strchars() - strchars("A\u20dd", true)->assert_equal(1) - enddef - - def Test_submatch() - var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' - var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} - var actual = substitute('A123456789', pat, Rep, '') - var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" - actual->assert_equal(expected) - enddef - - def Test_synID() - new - setline(1, "text") - synID(1, 1, true)->assert_equal(0) - bwipe! - enddef - - def Test_term_gettty() - if !has('terminal') - MissingFeature 'terminal' - else - var buf = Run_shell_in_terminal({}) - term_gettty(buf, true)->assert_notequal('') - StopShellInTerminal(buf) - endif - enddef - - def Test_term_start() - if !has('terminal') - MissingFeature 'terminal' - else - botright new - var winnr = winnr() - term_start(&shell, #{curwin: true}) - winnr()->assert_equal(winnr) - bwipe! - endif - enddef - - def Test_timer_paused() - var id = timer_start(50, {-> 0}) - timer_pause(id, true) - var info = timer_info(id) - info[0]['paused']->assert_equal(1) - timer_stop(id) - enddef - - def Test_win_splitmove() - split - win_splitmove(1, 2, #{vertical: true, rightbelow: true}) - close - enddef - - """"""" end of builtin functions - def Fibonacci(n: number): number if n < 2 return n --- 1460,1465 ---- *** ../vim-8.2.1875/src/testdir/test_vim9_builtin.vim 2020-10-21 14:21:23.422541479 +0200 --- src/testdir/test_vim9_builtin.vim 2020-10-21 14:20:41.130650402 +0200 *************** *** 0 **** --- 1,554 ---- + " Test using builtin functions in the Vim9 script language. + + source check.vim + source vim9.vim + + " Test for passing too many or too few arguments to builtin functions + func Test_internalfunc_arg_error() + let l =<< trim END + def! FArgErr(): float + return ceil(1.1, 2) + enddef + defcompile + END + call writefile(l, 'Xinvalidarg') + call assert_fails('so Xinvalidarg', 'E118:', '', 1, 'FArgErr') + let l =<< trim END + def! FArgErr(): float + return ceil() + enddef + defcompile + END + call writefile(l, 'Xinvalidarg') + call assert_fails('so Xinvalidarg', 'E119:', '', 1, 'FArgErr') + call delete('Xinvalidarg') + endfunc + + " Test for builtin functions returning different types + func Test_InternalFuncRetType() + let lines =<< trim END + def RetFloat(): float + return ceil(1.456) + enddef + + def RetListAny(): list + return items({'k': 'v'}) + enddef + + def RetListString(): list + return split('a:b:c', ':') + enddef + + def RetListDictAny(): list> + return getbufinfo() + enddef + + def RetDictNumber(): dict + return wordcount() + enddef + + def RetDictString(): dict + return environ() + enddef + END + call writefile(lines, 'Xscript') + source Xscript + + call RetFloat()->assert_equal(2.0) + call RetListAny()->assert_equal([['k', 'v']]) + call RetListString()->assert_equal(['a', 'b', 'c']) + call RetListDictAny()->assert_notequal([]) + call RetDictNumber()->assert_notequal({}) + call RetDictString()->assert_notequal({}) + call delete('Xscript') + endfunc + + def Test_abs() + assert_equal(0, abs(0)) + assert_equal(2, abs(-2)) + assert_equal(3, abs(3)) + CheckDefFailure(['abs("text")'], 'E1013: Argument 1: type mismatch, expected number but got string', 1) + if has('float') + assert_equal(0, abs(0)) + assert_equal(2.0, abs(-2.0)) + assert_equal(3.0, abs(3.0)) + endif + enddef + + def Test_add_list() + var l: list # defaults to empty list + add(l, 9) + assert_equal([9], l) + + var lines =<< trim END + var l: list + add(l, "x") + END + CheckDefFailure(lines, 'E1012:', 2) + + lines =<< trim END + var l: list = test_null_list() + add(l, 123) + END + CheckDefExecFailure(lines, 'E1130:', 2) + enddef + + def Test_add_blob() + var b1: blob = 0z12 + add(b1, 0x34) + assert_equal(0z1234, b1) + + var b2: blob # defaults to empty blob + add(b2, 0x67) + assert_equal(0z67, b2) + + var lines =<< trim END + var b: blob + add(b, "x") + END + CheckDefFailure(lines, 'E1012:', 2) + + lines =<< trim END + var b: blob = test_null_blob() + add(b, 123) + END + CheckDefExecFailure(lines, 'E1131:', 2) + enddef + + def Test_bufname() + split SomeFile + bufname('%')->assert_equal('SomeFile') + edit OtherFile + bufname('#')->assert_equal('SomeFile') + close + enddef + + def Test_bufnr() + var buf = bufnr() + bufnr('%')->assert_equal(buf) + + buf = bufnr('Xdummy', true) + buf->assert_notequal(-1) + exe 'bwipe! ' .. buf + enddef + + def Test_bufwinid() + var origwin = win_getid() + below split SomeFile + var SomeFileID = win_getid() + below split OtherFile + below split SomeFile + bufwinid('SomeFile')->assert_equal(SomeFileID) + + win_gotoid(origwin) + only + bwipe SomeFile + bwipe OtherFile + enddef + + def Test_call_call() + var l = [3, 2, 1] + call('reverse', [l]) + l->assert_equal([1, 2, 3]) + enddef + + def Test_char2nr() + char2nr('あ', true)->assert_equal(12354) + enddef + + def Test_col() + new + setline(1, 'asdf') + col([1, '$'])->assert_equal(5) + enddef + + def Test_copy_return_type() + var l = copy([1, 2, 3]) + var res = 0 + for n in l + res += n + endfor + res->assert_equal(6) + + var dl = deepcopy([1, 2, 3]) + res = 0 + for n in dl + res += n + endfor + res->assert_equal(6) + + dl = deepcopy([1, 2, 3], true) + enddef + + def Test_count() + count('ABC ABC ABC', 'b', true)->assert_equal(3) + count('ABC ABC ABC', 'b', false)->assert_equal(0) + enddef + + def Test_expand() + split SomeFile + expand('%', true, true)->assert_equal(['SomeFile']) + close + enddef + + def Test_extend_return_type() + var l = extend([1, 2], [3]) + var res = 0 + for n in l + res += n + endfor + res->assert_equal(6) + enddef + + + def Wrong_dict_key_type(items: list): list + return filter(items, {_, val -> get({val: 1}, 'x')}) + enddef + + def Test_filter_wrong_dict_key_type() + assert_fails('Wrong_dict_key_type([1, 2, 3])', 'E1012:') + enddef + + def Test_filter_return_type() + var l = filter([1, 2, 3], {-> 1}) + var res = 0 + for n in l + res += n + endfor + res->assert_equal(6) + enddef + + + def Test_garbagecollect() + garbagecollect(true) + enddef + + def Test_getbufinfo() + var bufinfo = getbufinfo(bufnr()) + getbufinfo('%')->assert_equal(bufinfo) + + edit Xtestfile1 + hide edit Xtestfile2 + hide enew + getbufinfo(#{bufloaded: true, buflisted: true, bufmodified: false}) + ->len()->assert_equal(3) + bwipe Xtestfile1 Xtestfile2 + enddef + + def Test_getbufline() + e SomeFile + var buf = bufnr() + e # + var lines = ['aaa', 'bbb', 'ccc'] + setbufline(buf, 1, lines) + getbufline('#', 1, '$')->assert_equal(lines) + + bwipe! + enddef + + def Test_getchangelist() + new + setline(1, 'some text') + var changelist = bufnr()->getchangelist() + getchangelist('%')->assert_equal(changelist) + bwipe! + enddef + + def Test_getchar() + while getchar(0) + endwhile + getchar(true)->assert_equal(0) + enddef + + def Test_getcompletion() + set wildignore=*.vim,*~ + var l = getcompletion('run', 'file', true) + l->assert_equal([]) + set wildignore& + enddef + + def Test_getloclist_return_type() + var l = getloclist(1) + l->assert_equal([]) + + var d = getloclist(1, #{items: 0}) + d->assert_equal(#{items: []}) + enddef + + def Test_getqflist_return_type() + var l = getqflist() + l->assert_equal([]) + + var d = getqflist(#{items: 0}) + d->assert_equal(#{items: []}) + enddef + + def Test_getreg() + var lines = ['aaa', 'bbb', 'ccc'] + setreg('a', lines) + getreg('a', true, true)->assert_equal(lines) + enddef + + def Test_getreg_return_type() + var s1: string = getreg('"') + var s2: string = getreg('"', 1) + var s3: list = getreg('"', 1, 1) + enddef + + def Test_glob() + glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim']) + enddef + + def Test_globpath() + globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim']) + enddef + + def Test_has() + has('eval', true)->assert_equal(1) + enddef + + def Test_hasmapto() + hasmapto('foobar', 'i', true)->assert_equal(0) + iabbrev foo foobar + hasmapto('foobar', 'i', true)->assert_equal(1) + iunabbrev foo + enddef + + def Test_index() + index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3) + enddef + + def Test_insert_return_type() + var l = insert([2, 1], 3) + var res = 0 + for n in l + res += n + endfor + res->assert_equal(6) + enddef + + def Test_keys_return_type() + const var: list = #{a: 1, b: 2}->keys() + var->assert_equal(['a', 'b']) + enddef + + def Test_list2str_str2list_utf8() + var s = "\u3042\u3044" + var l = [0x3042, 0x3044] + str2list(s, true)->assert_equal(l) + list2str(l, true)->assert_equal(s) + enddef + + def SID(): number + return expand('') + ->matchstr('\zs\d\+\ze_$') + ->str2nr() + enddef + + def Test_maparg() + var lnum = str2nr(expand('')) + map foo bar + maparg('foo', '', false, true)->assert_equal(#{ + lnum: lnum + 1, + script: 0, + mode: ' ', + silent: 0, + noremap: 0, + lhs: 'foo', + lhsraw: 'foo', + nowait: 0, + expr: 0, + sid: SID(), + rhs: 'bar', + buffer: 0}) + unmap foo + enddef + + def Test_mapcheck() + iabbrev foo foobar + mapcheck('foo', 'i', true)->assert_equal('foobar') + iunabbrev foo + enddef + + def Test_maparg_mapset() + nnoremap :echo "hit F3" + var mapsave = maparg('', 'n', false, true) + mapset('n', false, mapsave) + + nunmap + enddef + + def Test_nr2char() + nr2char(97, true)->assert_equal('a') + enddef + + def Test_readdir() + eval expand('sautest')->readdir({e -> e[0] !=# '.'}) + eval expand('sautest')->readdirex({e -> e.name[0] !=# '.'}) + enddef + + def Test_remove_return_type() + var l = remove(#{one: [1, 2], two: [3, 4]}, 'one') + var res = 0 + for n in l + res += n + endfor + res->assert_equal(3) + enddef + + def Test_reverse_return_type() + var l = reverse([1, 2, 3]) + var res = 0 + for n in l + res += n + endfor + res->assert_equal(6) + enddef + + def Test_search() + new + setline(1, ['foo', 'bar']) + var val = 0 + # skip expr returns boolean + search('bar', 'W', 0, 0, {-> val == 1})->assert_equal(2) + :1 + search('bar', 'W', 0, 0, {-> val == 0})->assert_equal(0) + # skip expr returns number, only 0 and 1 are accepted + :1 + search('bar', 'W', 0, 0, {-> 0})->assert_equal(2) + :1 + search('bar', 'W', 0, 0, {-> 1})->assert_equal(0) + assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') + assert_fails("search('bar', '', 0, 0, {-> -1})", 'E1023:') + enddef + + def Test_searchcount() + new + setline(1, "foo bar") + :/foo + searchcount(#{recompute: true}) + ->assert_equal(#{ + exact_match: 1, + current: 1, + total: 1, + maxcount: 99, + incomplete: 0}) + bwipe! + enddef + + def Test_searchdecl() + searchdecl('blah', true, true)->assert_equal(1) + enddef + + def Test_setbufvar() + setbufvar(bufnr('%'), '&syntax', 'vim') + &syntax->assert_equal('vim') + setbufvar(bufnr('%'), '&ts', 16) + &ts->assert_equal(16) + settabwinvar(1, 1, '&syntax', 'vam') + &syntax->assert_equal('vam') + settabwinvar(1, 1, '&ts', 15) + &ts->assert_equal(15) + setlocal ts=8 + + setbufvar('%', 'myvar', 123) + getbufvar('%', 'myvar')->assert_equal(123) + enddef + + def Test_setloclist() + var items = [#{filename: '/tmp/file', lnum: 1, valid: true}] + var what = #{items: items} + setqflist([], ' ', what) + setloclist(0, [], ' ', what) + enddef + + def Test_setreg() + setreg('a', ['aaa', 'bbb', 'ccc']) + var reginfo = getreginfo('a') + setreg('a', reginfo) + getreginfo('a')->assert_equal(reginfo) + enddef + + def Test_spellsuggest() + if !has('spell') + MissingFeature 'spell' + else + spellsuggest('marrch', 1, true)->assert_equal(['March']) + endif + enddef + + def Test_sort_return_type() + var res: list + res = [1, 2, 3]->sort() + enddef + + def Test_sort_argument() + var res = ['b', 'a', 'c']->sort('i') + res->assert_equal(['a', 'b', 'c']) + enddef + + def Test_split() + split(' aa bb ', '\W\+', true)->assert_equal(['', 'aa', 'bb', '']) + enddef + + def Test_str2nr() + str2nr("1'000'000", 10, true)->assert_equal(1000000) + enddef + + def Test_strchars() + strchars("A\u20dd", true)->assert_equal(1) + enddef + + def Test_submatch() + var pat = 'A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)' + var Rep = {-> range(10)->map({_, v -> submatch(v, true)})->string()} + var actual = substitute('A123456789', pat, Rep, '') + var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]" + actual->assert_equal(expected) + enddef + + def Test_synID() + new + setline(1, "text") + synID(1, 1, true)->assert_equal(0) + bwipe! + enddef + + def Test_term_gettty() + if !has('terminal') + MissingFeature 'terminal' + else + var buf = Run_shell_in_terminal({}) + term_gettty(buf, true)->assert_notequal('') + StopShellInTerminal(buf) + endif + enddef + + def Test_term_start() + if !has('terminal') + MissingFeature 'terminal' + else + botright new + var winnr = winnr() + term_start(&shell, #{curwin: true}) + winnr()->assert_equal(winnr) + bwipe! + endif + enddef + + def Test_timer_paused() + var id = timer_start(50, {-> 0}) + timer_pause(id, true) + var info = timer_info(id) + info[0]['paused']->assert_equal(1) + timer_stop(id) + enddef + + def Test_win_splitmove() + split + win_splitmove(1, 2, #{vertical: true, rightbelow: true}) + close + enddef + + + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker *** ../vim-8.2.1875/src/testdir/Make_all.mak 2020-10-12 20:31:11.291727542 +0200 --- src/testdir/Make_all.mak 2020-10-21 14:09:09.400615057 +0200 *************** *** 31,36 **** --- 31,37 ---- # Tests for Vim9 script. TEST_VIM9 = \ test_vim9_assign \ + test_vim9_builtin \ test_vim9_cmd \ test_vim9_disassemble \ test_vim9_expr \ *************** *** 40,45 **** --- 41,47 ---- TEST_VIM9_RES = \ test_vim9_assign.res \ + test_vim9_builtin.res \ test_vim9_cmd.res \ test_vim9_disassemble.res \ test_vim9_expr.res \ *** ../vim-8.2.1875/src/version.c 2020-10-21 12:37:56.270973451 +0200 --- src/version.c 2020-10-21 13:24:20.055852276 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1876, /**/ -- From "know your smileys": :-* A big kiss! /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///