# HG changeset patch # User vimboss # Date 1104786361 0 # Node ID dbf53ece2e23fd6e8652c531ce7976f54ae85635 # Parent 225cc00b2eda773603aaf2849ac03364d3cc842c updated for version 7.0029 diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt --- a/runtime/doc/starting.txt +++ b/runtime/doc/starting.txt @@ -1,4 +1,4 @@ -*starting.txt* For Vim version 7.0aa. Last change: 2004 Dec 29 +*starting.txt* For Vim version 7.0aa. Last change: 2005 Jan 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1264,7 +1264,7 @@ The viminfo file is used to store: - The command line history. - The search string history. - The input-line history. -- Contents of registers. +- Contents of non-empty registers. - Marks for several files. - File marks, pointing to locations in files. - Last search/substitute pattern (for 'n' and '&'). diff --git a/runtime/doc/tagsrch.txt b/runtime/doc/tagsrch.txt --- a/runtime/doc/tagsrch.txt +++ b/runtime/doc/tagsrch.txt @@ -1,4 +1,4 @@ -*tagsrch.txt* For Vim version 7.0aa. Last change: 2004 Jul 23 +*tagsrch.txt* For Vim version 7.0aa. Last change: 2005 Jan 02 VIM REFERENCE MANUAL by Bram Moolenaar @@ -60,7 +60,7 @@ tag, you will get the telnet prompt inst changing or disabling the default escape key. See the telnet man page. You can 'telnet -E {Hostname}' to disable the escape character, or 'telnet -e {EscapeCharacter} {Hostname}' to specify another escape character. If -possible, try to use "rsh" instead of "telnet" to avoid this problem. +possible, try to use "ssh" instead of "telnet" to avoid this problem. *tag-priority* When there are multiple matches for a tag, this priority is used: diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2005 Jan 01 +*todo.txt* For Vim version 7.0aa. Last change: 2005 Jan 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -30,10 +30,34 @@ be worked on, but only if you sponsor Vi *known-bugs* -------------------- Known bugs and current work ----------------------- +List data type: +- ":let list[expr] = expr" +- ":let [a, b] = [1, 2]" +- ":let [a, b; rest] = [1, 2, 3, 4]" +- "for a in list" +- "for [a, b] in [[1, 2], [3, 4]]" +- == (same value) and "is" (same list) +- add many functions: + call(func, list) call function + keys(list) list of all indexes 0 - len(list) + repeat(list, count) return list concatenated count times + concat(list1, list2) return list1 and list2 concatenated + extend(list1, list2) concatenate list2 to list 1 + extend(list1, list2, idx) prepend list2 before idx in list1 + count(list, item) nr of times item appears in list + index(list, item) lowest index of item in list + pop(list[, idx]) removes item at idx (default: last) + pop(list, idx1, idx2) removes items idx1 to idx2, returns them + reverse(list) reverses order + sort(list[, func]) sort; func compares items + getval(list, idx[, default]) get value at idx or default + file2lines() + file2words() + patch for QuickFixCmdPre and QuickFixCmdPost autocommands. (Ciaran McCreesh, 2005 Jan 1) -New toolbar button from Martin Dalecki: +New Motif toolbar button from Martin Dalecki: - add remark in version7.txt - check if it works for pixmap loaded from a file. @@ -60,11 +84,10 @@ PLANNED FOR VERSION 7.0: + can include NUL characters - setline() will have problems with NL vs NUL. Can use list of numbers instead (inefficient though). + Also: for strings up to 3 bytes don't allocate memory, VAR_STRINGX. - new DATA TYPES: - None? (or use empty string?) - - list - dictionary - - function reference Check old patch from Robert Webb for array support. Add type checking? See ~/vim/ideas.txt. - Add SPELLCHECKER, with easy to add support for many languages. diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2005 Jan 01 +*version7.txt* For Vim version 7.0aa. Last change: 2005 Jan 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -381,6 +381,8 @@ Included a few improvements for Motif fr contents ourselves to make them handle fonts in a way configurable by Vim and a bit less dependent on the X11 font management. +When a register is empty it is not stored in the viminfo file. + ============================================================================== COMPILE TIME CHANGES *compile-changes-7* @@ -627,6 +629,9 @@ break, resulting in "selected 202 of 201 Motif: fonts were not used for dialog components. (Martin Dalecki) +Motif: After using a toolbar button the keyboard focus would be on the toolbar +(Lesstif problem). (Martin Dalecki) + When using "y`x" where mark x is in the first column, the last line was not included. diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -37,26 +37,66 @@ typedef int varnumber_T; #endif /* - * Structure to hold an internal variable. + * Structure to hold an internal variable without a name. + */ +typedef struct +{ + char v_type; /* see below: VAR_NUMBER, VAR_STRING, etc. */ + union + { + varnumber_T v_number; /* number value */ + char_u *v_string; /* string value (can be NULL!) */ + struct listvar_S *v_list; /* list value (can be NULL!) */ + } vval; +} typeval; + +/* Values for "v_type". */ +#define VAR_UNKNOWN 0 +#define VAR_NUMBER 1 /* "v_number" is used */ +#define VAR_STRING 2 /* "v_string" is used */ +#define VAR_FUNC 3 /* "v_string" is function name */ +#define VAR_LIST 4 /* "v_list" is used */ + +/* + * Structure to hold an internal variable with a name. + * The "tv" must come first, so that this can be used as a "typeval" as well. */ typedef struct { - char_u *var_name; /* name of variable */ - char var_type; /* VAR_NUMBER or VAR_STRING */ - union - { - varnumber_T var_number; /* number value */ - char_u *var_string; /* string value (Careful: can be NULL!) */ - } var_val; + typeval tv; /* type and value of the variable */ + char_u *v_name; /* name of variable */ } var; -#define VAR_UNKNOWN 0 -#define VAR_NUMBER 1 -#define VAR_STRING 2 - typedef var * VAR; /* + * Structure to hold an item of a list: an internal variable without a name. + */ +struct listitem_S +{ + struct listitem_S *li_next; /* next item in list */ + struct listitem_S *li_prev; /* previous item in list */ + typeval li_tv; /* type and value of the variable */ +}; + +typedef struct listitem_S listitem; + +/* + * Structure to hold the info about a list. + */ +struct listvar_S +{ + int lv_refcount; /* reference count */ + listitem *lv_first; /* first item, NULL if none */ + listitem *lv_last; /* last item, NULL if none */ +}; + +typedef struct listvar_S listvar; + +#define VAR_LIST_MAXNEST 100 /* maximum nesting of lists */ +static char_u *e_listidx = (char_u *)N_("E999: list index out of range: %ld"); + +/* * All user-defined global variables are stored in "variables". */ garray_T variables = {0, 0, sizeof(var), 4, NULL}; @@ -114,12 +154,12 @@ struct funccall int linenr; /* next line to be executed */ int returned; /* ":return" used */ int argcount; /* nr of arguments */ - VAR argvars; /* arguments */ + typeval *argvars; /* arguments */ var a0_var; /* "a:0" variable */ var firstline; /* "a:firstline" variable */ var lastline; /* "a:lastline" variable */ garray_T l_vars; /* local function variables */ - VAR retvar; /* return value variable */ + typeval *retvar; /* return value variable */ linenr_T breakpoint; /* next line with breakpoint or zero */ int dbg_tick; /* debug_tick when breakpoint was set */ int level; /* top nesting level of executed function */ @@ -236,190 +276,214 @@ struct vimvar }; static int eval0 __ARGS((char_u *arg, VAR retvar, char_u **nextcmd, int evaluate)); -static int eval1 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval2 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval3 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval4 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval5 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval6 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int eval7 __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int get_option_var __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int get_string_var __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int get_lit_string_var __ARGS((char_u **arg, VAR retvar, int evaluate)); -static int get_env_var __ARGS((char_u **arg, VAR retvar, int evaluate)); +static int eval1 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval2 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval3 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval4 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval5 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval6 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval7 __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int eval_index __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int get_option_vartv __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int get_string_vartv __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int get_lit_string_vartv __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static int get_list_vartv __ARGS((char_u **arg, typeval *retvar, int evaluate)); +static listvar *list_alloc __ARGS((void)); +static void list_unref __ARGS((listvar *l)); +static void list_free __ARGS((listvar *l)); +static listitem *listitem_alloc __ARGS((void)); +static void listitem_free __ARGS((listitem *item)); +static long list_len __ARGS((listvar *l)); +static listitem *list_find __ARGS((listvar *l, long n)); +static void list_append __ARGS((listvar *l, listitem *item)); +static int list_append_tv __ARGS((listvar *l, typeval *tv)); +static listvar *list_copy __ARGS((listvar *orig, int deep)); +static listitem *list_getrem __ARGS((listvar *l, long n)); +static char_u *list2string __ARGS((typeval *tv)); +static char_u *tv2string __ARGS((typeval *tv, char_u **tofree)); +static int get_env_vartv __ARGS((char_u **arg, typeval *retvar, int evaluate)); static int find_internal_func __ARGS((char_u *name)); -static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); -static int call_func __ARGS((char_u *name, int len, VAR retvar, int argcount, VAR argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); -static void f_append __ARGS((VAR argvars, VAR retvar)); -static void f_argc __ARGS((VAR argvars, VAR retvar)); -static void f_argidx __ARGS((VAR argvars, VAR retvar)); -static void f_argv __ARGS((VAR argvars, VAR retvar)); -static void f_browse __ARGS((VAR argvars, VAR retvar)); -static void f_browsedir __ARGS((VAR argvars, VAR retvar)); -static buf_T *find_buffer __ARGS((VAR avar)); -static void f_bufexists __ARGS((VAR argvars, VAR retvar)); -static void f_buflisted __ARGS((VAR argvars, VAR retvar)); -static void f_bufloaded __ARGS((VAR argvars, VAR retvar)); -static buf_T *get_buf_var __ARGS((VAR avar)); -static void f_bufname __ARGS((VAR argvars, VAR retvar)); -static void f_bufnr __ARGS((VAR argvars, VAR retvar)); -static void f_bufwinnr __ARGS((VAR argvars, VAR retvar)); -static void f_byte2line __ARGS((VAR argvars, VAR retvar)); -static void f_byteidx __ARGS((VAR argvars, VAR retvar)); -static void f_char2nr __ARGS((VAR argvars, VAR retvar)); -static void f_cindent __ARGS((VAR argvars, VAR retvar)); -static void f_col __ARGS((VAR argvars, VAR retvar)); -static void f_confirm __ARGS((VAR argvars, VAR retvar)); -static void f_cscope_connection __ARGS((VAR argvars, VAR retvar)); -static void f_cursor __ARGS((VAR argsvars, VAR retvar)); -static void f_delete __ARGS((VAR argvars, VAR retvar)); -static void f_did_filetype __ARGS((VAR argvars, VAR retvar)); -static void f_diff_filler __ARGS((VAR argvars, VAR retvar)); -static void f_diff_hlID __ARGS((VAR argvars, VAR retvar)); -static void f_escape __ARGS((VAR argvars, VAR retvar)); -static void f_eventhandler __ARGS((VAR argvars, VAR retvar)); -static void f_executable __ARGS((VAR argvars, VAR retvar)); -static void f_exists __ARGS((VAR argvars, VAR retvar)); -static void f_expand __ARGS((VAR argvars, VAR retvar)); -static void f_filereadable __ARGS((VAR argvars, VAR retvar)); -static void f_filewritable __ARGS((VAR argvars, VAR retvar)); -static void f_finddir __ARGS((VAR argvars, VAR retvar)); -static void f_findfile __ARGS((VAR argvars, VAR retvar)); -static void f_findfilendir __ARGS((VAR argvars, VAR retvar, int dir)); -static void f_fnamemodify __ARGS((VAR argvars, VAR retvar)); -static void f_foldclosed __ARGS((VAR argvars, VAR retvar)); -static void f_foldclosedend __ARGS((VAR argvars, VAR retvar)); -static void foldclosed_both __ARGS((VAR argvars, VAR retvar, int end)); -static void f_foldlevel __ARGS((VAR argvars, VAR retvar)); -static void f_foldtext __ARGS((VAR argvars, VAR retvar)); -static void f_foldtextresult __ARGS((VAR argvars, VAR retvar)); -static void f_foreground __ARGS((VAR argvars, VAR retvar)); -static void f_getbufvar __ARGS((VAR argvars, VAR retvar)); -static void f_getchar __ARGS((VAR argvars, VAR retvar)); -static void f_getcharmod __ARGS((VAR argvars, VAR retvar)); -static void f_getcmdline __ARGS((VAR argvars, VAR retvar)); -static void f_getcmdpos __ARGS((VAR argvars, VAR retvar)); -static void f_getcwd __ARGS((VAR argvars, VAR retvar)); -static void f_getfontname __ARGS((VAR argvars, VAR retvar)); -static void f_getfperm __ARGS((VAR argvars, VAR retvar)); -static void f_getfsize __ARGS((VAR argvars, VAR retvar)); -static void f_getftime __ARGS((VAR argvars, VAR retvar)); -static void f_getftype __ARGS((VAR argvars, VAR retvar)); -static void f_getline __ARGS((VAR argvars, VAR retvar)); -static void f_getreg __ARGS((VAR argvars, VAR retvar)); -static void f_getregtype __ARGS((VAR argvars, VAR retvar)); -static void f_getwinposx __ARGS((VAR argvars, VAR retvar)); -static void f_getwinposy __ARGS((VAR argvars, VAR retvar)); -static void f_getwinvar __ARGS((VAR argvars, VAR retvar)); -static void f_glob __ARGS((VAR argvars, VAR retvar)); -static void f_globpath __ARGS((VAR argvars, VAR retvar)); -static void f_has __ARGS((VAR argvars, VAR retvar)); -static void f_hasmapto __ARGS((VAR argvars, VAR retvar)); -static void f_histadd __ARGS((VAR argvars, VAR retvar)); -static void f_histdel __ARGS((VAR argvars, VAR retvar)); -static void f_histget __ARGS((VAR argvars, VAR retvar)); -static void f_histnr __ARGS((VAR argvars, VAR retvar)); -static void f_hlexists __ARGS((VAR argvars, VAR retvar)); -static void f_hlID __ARGS((VAR argvars, VAR retvar)); -static void f_hostname __ARGS((VAR argvars, VAR retvar)); -static void f_iconv __ARGS((VAR argvars, VAR retvar)); -static void f_indent __ARGS((VAR argvars, VAR retvar)); -static void f_isdirectory __ARGS((VAR argvars, VAR retvar)); -static void f_input __ARGS((VAR argvars, VAR retvar)); -static void f_inputdialog __ARGS((VAR argvars, VAR retvar)); -static void f_inputrestore __ARGS((VAR argvars, VAR retvar)); -static void f_inputsave __ARGS((VAR argvars, VAR retvar)); -static void f_inputsecret __ARGS((VAR argvars, VAR retvar)); -static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar)); -static void f_libcall __ARGS((VAR argvars, VAR retvar)); -static void f_libcallnr __ARGS((VAR argvars, VAR retvar)); -static void libcall_common __ARGS((VAR argvars, VAR retvar, int type)); -static void f_line __ARGS((VAR argvars, VAR retvar)); -static void f_line2byte __ARGS((VAR argvars, VAR retvar)); -static void f_lispindent __ARGS((VAR argvars, VAR retvar)); -static void f_localtime __ARGS((VAR argvars, VAR retvar)); -static void f_maparg __ARGS((VAR argvars, VAR retvar)); -static void f_mapcheck __ARGS((VAR argvars, VAR retvar)); -static void get_maparg __ARGS((VAR argvars, VAR retvar, int exact)); -static void f_match __ARGS((VAR argvars, VAR retvar)); -static void f_matchend __ARGS((VAR argvars, VAR retvar)); -static void f_matchstr __ARGS((VAR argvars, VAR retvar)); -static void f_mode __ARGS((VAR argvars, VAR retvar)); -static void f_nextnonblank __ARGS((VAR argvars, VAR retvar)); -static void f_nr2char __ARGS((VAR argvars, VAR retvar)); -static void f_prevnonblank __ARGS((VAR argvars, VAR retvar)); -static void f_setbufvar __ARGS((VAR argvars, VAR retvar)); -static void f_setcmdpos __ARGS((VAR argvars, VAR retvar)); -static void f_setwinvar __ARGS((VAR argvars, VAR retvar)); -static void f_rename __ARGS((VAR argvars, VAR retvar)); -static void f_resolve __ARGS((VAR argvars, VAR retvar)); -static void f_search __ARGS((VAR argvars, VAR retvar)); -static void f_searchpair __ARGS((VAR argvars, VAR retvar)); -static int get_search_arg __ARGS((VAR varp, int *flagsp)); -static void f_remote_expr __ARGS((VAR argvars, VAR retvar)); -static void f_remote_foreground __ARGS((VAR argvars, VAR retvar)); -static void f_remote_peek __ARGS((VAR argvars, VAR retvar)); -static void f_remote_read __ARGS((VAR argvars, VAR retvar)); -static void f_remote_send __ARGS((VAR argvars, VAR retvar)); -static void f_repeat __ARGS((VAR argvars, VAR retvar)); -static void f_server2client __ARGS((VAR argvars, VAR retvar)); -static void f_serverlist __ARGS((VAR argvars, VAR retvar)); -static void f_setline __ARGS((VAR argvars, VAR retvar)); -static void f_setreg __ARGS((VAR argvars, VAR retvar)); -static void f_simplify __ARGS((VAR argvars, VAR retvar)); -static void find_some_match __ARGS((VAR argvars, VAR retvar, int start)); -static void f_strftime __ARGS((VAR argvars, VAR retvar)); -static void f_stridx __ARGS((VAR argvars, VAR retvar)); -static void f_strlen __ARGS((VAR argvars, VAR retvar)); -static void f_strpart __ARGS((VAR argvars, VAR retvar)); -static void f_strridx __ARGS((VAR argvars, VAR retvar)); -static void f_strtrans __ARGS((VAR argvars, VAR retvar)); -static void f_synID __ARGS((VAR argvars, VAR retvar)); -static void f_synIDattr __ARGS((VAR argvars, VAR retvar)); -static void f_synIDtrans __ARGS((VAR argvars, VAR retvar)); -static void f_system __ARGS((VAR argvars, VAR retvar)); -static void f_submatch __ARGS((VAR argvars, VAR retvar)); -static void f_substitute __ARGS((VAR argvars, VAR retvar)); -static void f_tempname __ARGS((VAR argvars, VAR retvar)); -static void f_tolower __ARGS((VAR argvars, VAR retvar)); -static void f_toupper __ARGS((VAR argvars, VAR retvar)); -static void f_tr __ARGS((VAR argvars, VAR retvar)); -static void f_type __ARGS((VAR argvars, VAR retvar)); -static void f_virtcol __ARGS((VAR argvars, VAR retvar)); -static void f_visualmode __ARGS((VAR argvars, VAR retvar)); -static void f_winbufnr __ARGS((VAR argvars, VAR retvar)); -static void f_wincol __ARGS((VAR argvars, VAR retvar)); -static void f_winheight __ARGS((VAR argvars, VAR retvar)); -static void f_winline __ARGS((VAR argvars, VAR retvar)); -static void f_winnr __ARGS((VAR argvars, VAR retvar)); -static void f_winrestcmd __ARGS((VAR argvars, VAR retvar)); -static void f_winwidth __ARGS((VAR argvars, VAR retvar)); -static win_T *find_win_by_nr __ARGS((VAR vp)); -static pos_T *var2fpos __ARGS((VAR varp, int lnum)); +static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); +static int get_func_vartv __ARGS((char_u *name, int len, typeval *retvar, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); +static int call_func __ARGS((char_u *name, int len, typeval *retvar, int argcount, typeval *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); +static void f_append __ARGS((typeval *argvars, typeval *retvar)); +static void f_argc __ARGS((typeval *argvars, typeval *retvar)); +static void f_argidx __ARGS((typeval *argvars, typeval *retvar)); +static void f_argv __ARGS((typeval *argvars, typeval *retvar)); +static void f_browse __ARGS((typeval *argvars, typeval *retvar)); +static void f_browsedir __ARGS((typeval *argvars, typeval *retvar)); +static buf_T *find_buffer __ARGS((typeval *avar)); +static void f_bufexists __ARGS((typeval *argvars, typeval *retvar)); +static void f_buflisted __ARGS((typeval *argvars, typeval *retvar)); +static void f_bufloaded __ARGS((typeval *argvars, typeval *retvar)); +static buf_T *get_buf_vartv __ARGS((typeval *avar)); +static void f_bufname __ARGS((typeval *argvars, typeval *retvar)); +static void f_bufnr __ARGS((typeval *argvars, typeval *retvar)); +static void f_bufwinnr __ARGS((typeval *argvars, typeval *retvar)); +static void f_byte2line __ARGS((typeval *argvars, typeval *retvar)); +static void f_byteidx __ARGS((typeval *argvars, typeval *retvar)); +static void f_char2nr __ARGS((typeval *argvars, typeval *retvar)); +static void f_cindent __ARGS((typeval *argvars, typeval *retvar)); +static void f_col __ARGS((typeval *argvars, typeval *retvar)); +static void f_confirm __ARGS((typeval *argvars, typeval *retvar)); +static void f_copy __ARGS((typeval *argvars, typeval *retvar)); +static void f_cscope_connection __ARGS((typeval *argvars, typeval *retvar)); +static void f_cursor __ARGS((typeval *argsvars, typeval *retvar)); +static void f_deepcopy __ARGS((typeval *argvars, typeval *retvar)); +static void f_delete __ARGS((typeval *argvars, typeval *retvar)); +static void f_did_filetype __ARGS((typeval *argvars, typeval *retvar)); +static void f_diff_filler __ARGS((typeval *argvars, typeval *retvar)); +static void f_diff_hlID __ARGS((typeval *argvars, typeval *retvar)); +static void f_escape __ARGS((typeval *argvars, typeval *retvar)); +static void f_eventhandler __ARGS((typeval *argvars, typeval *retvar)); +static void f_executable __ARGS((typeval *argvars, typeval *retvar)); +static void f_exists __ARGS((typeval *argvars, typeval *retvar)); +static void f_expand __ARGS((typeval *argvars, typeval *retvar)); +static void f_filereadable __ARGS((typeval *argvars, typeval *retvar)); +static void f_filewritable __ARGS((typeval *argvars, typeval *retvar)); +static void f_finddir __ARGS((typeval *argvars, typeval *retvar)); +static void f_findfile __ARGS((typeval *argvars, typeval *retvar)); +static void f_findfilendir __ARGS((typeval *argvars, typeval *retvar, int dir)); +static void f_fnamemodify __ARGS((typeval *argvars, typeval *retvar)); +static void f_foldclosed __ARGS((typeval *argvars, typeval *retvar)); +static void f_foldclosedend __ARGS((typeval *argvars, typeval *retvar)); +static void foldclosed_both __ARGS((typeval *argvars, typeval *retvar, int end)); +static void f_foldlevel __ARGS((typeval *argvars, typeval *retvar)); +static void f_foldtext __ARGS((typeval *argvars, typeval *retvar)); +static void f_foldtextresult __ARGS((typeval *argvars, typeval *retvar)); +static void f_foreground __ARGS((typeval *argvars, typeval *retvar)); +static void f_function __ARGS((typeval *argvars, typeval *retvar)); +static void f_getbufvar __ARGS((typeval *argvars, typeval *retvar)); +static void f_getchar __ARGS((typeval *argvars, typeval *retvar)); +static void f_getcharmod __ARGS((typeval *argvars, typeval *retvar)); +static void f_getcmdline __ARGS((typeval *argvars, typeval *retvar)); +static void f_getcmdpos __ARGS((typeval *argvars, typeval *retvar)); +static void f_getcwd __ARGS((typeval *argvars, typeval *retvar)); +static void f_getfontname __ARGS((typeval *argvars, typeval *retvar)); +static void f_getfperm __ARGS((typeval *argvars, typeval *retvar)); +static void f_getfsize __ARGS((typeval *argvars, typeval *retvar)); +static void f_getftime __ARGS((typeval *argvars, typeval *retvar)); +static void f_getftype __ARGS((typeval *argvars, typeval *retvar)); +static void f_getline __ARGS((typeval *argvars, typeval *retvar)); +static void f_getreg __ARGS((typeval *argvars, typeval *retvar)); +static void f_getregtype __ARGS((typeval *argvars, typeval *retvar)); +static void f_getwinposx __ARGS((typeval *argvars, typeval *retvar)); +static void f_getwinposy __ARGS((typeval *argvars, typeval *retvar)); +static void f_getwinvar __ARGS((typeval *argvars, typeval *retvar)); +static void f_glob __ARGS((typeval *argvars, typeval *retvar)); +static void f_globpath __ARGS((typeval *argvars, typeval *retvar)); +static void f_has __ARGS((typeval *argvars, typeval *retvar)); +static void f_hasmapto __ARGS((typeval *argvars, typeval *retvar)); +static void f_histadd __ARGS((typeval *argvars, typeval *retvar)); +static void f_histdel __ARGS((typeval *argvars, typeval *retvar)); +static void f_histget __ARGS((typeval *argvars, typeval *retvar)); +static void f_histnr __ARGS((typeval *argvars, typeval *retvar)); +static void f_hlexists __ARGS((typeval *argvars, typeval *retvar)); +static void f_hlID __ARGS((typeval *argvars, typeval *retvar)); +static void f_hostname __ARGS((typeval *argvars, typeval *retvar)); +static void f_iconv __ARGS((typeval *argvars, typeval *retvar)); +static void f_indent __ARGS((typeval *argvars, typeval *retvar)); +static void f_insert __ARGS((typeval *argvars, typeval *retvar)); +static void f_isdirectory __ARGS((typeval *argvars, typeval *retvar)); +static void f_input __ARGS((typeval *argvars, typeval *retvar)); +static void f_inputdialog __ARGS((typeval *argvars, typeval *retvar)); +static void f_inputrestore __ARGS((typeval *argvars, typeval *retvar)); +static void f_inputsave __ARGS((typeval *argvars, typeval *retvar)); +static void f_inputsecret __ARGS((typeval *argvars, typeval *retvar)); +static void f_last_buffer_nr __ARGS((typeval *argvars, typeval *retvar)); +static void f_len __ARGS((typeval *argvars, typeval *retvar)); +static void f_libcall __ARGS((typeval *argvars, typeval *retvar)); +static void f_libcallnr __ARGS((typeval *argvars, typeval *retvar)); +static void libcall_common __ARGS((typeval *argvars, typeval *retvar, int type)); +static void f_line __ARGS((typeval *argvars, typeval *retvar)); +static void f_line2byte __ARGS((typeval *argvars, typeval *retvar)); +static void f_lispindent __ARGS((typeval *argvars, typeval *retvar)); +static void f_localtime __ARGS((typeval *argvars, typeval *retvar)); +static void f_maparg __ARGS((typeval *argvars, typeval *retvar)); +static void f_mapcheck __ARGS((typeval *argvars, typeval *retvar)); +static void get_maparg __ARGS((typeval *argvars, typeval *retvar, int exact)); +static void f_match __ARGS((typeval *argvars, typeval *retvar)); +static void f_matchend __ARGS((typeval *argvars, typeval *retvar)); +static void f_matchstr __ARGS((typeval *argvars, typeval *retvar)); +static void f_mode __ARGS((typeval *argvars, typeval *retvar)); +static void f_nextnonblank __ARGS((typeval *argvars, typeval *retvar)); +static void f_nr2char __ARGS((typeval *argvars, typeval *retvar)); +static void f_prevnonblank __ARGS((typeval *argvars, typeval *retvar)); +static void f_setbufvar __ARGS((typeval *argvars, typeval *retvar)); +static void f_setcmdpos __ARGS((typeval *argvars, typeval *retvar)); +static void f_setwinvar __ARGS((typeval *argvars, typeval *retvar)); +static void f_remove __ARGS((typeval *argvars, typeval *retvar)); +static void f_rename __ARGS((typeval *argvars, typeval *retvar)); +static void f_resolve __ARGS((typeval *argvars, typeval *retvar)); +static void f_search __ARGS((typeval *argvars, typeval *retvar)); +static void f_searchpair __ARGS((typeval *argvars, typeval *retvar)); +static int get_search_arg __ARGS((typeval *varp, int *flagsp)); +static void f_remote_expr __ARGS((typeval *argvars, typeval *retvar)); +static void f_remote_foreground __ARGS((typeval *argvars, typeval *retvar)); +static void f_remote_peek __ARGS((typeval *argvars, typeval *retvar)); +static void f_remote_read __ARGS((typeval *argvars, typeval *retvar)); +static void f_remote_send __ARGS((typeval *argvars, typeval *retvar)); +static void f_repeat __ARGS((typeval *argvars, typeval *retvar)); +static void f_server2client __ARGS((typeval *argvars, typeval *retvar)); +static void f_serverlist __ARGS((typeval *argvars, typeval *retvar)); +static void f_setline __ARGS((typeval *argvars, typeval *retvar)); +static void f_setreg __ARGS((typeval *argvars, typeval *retvar)); +static void f_simplify __ARGS((typeval *argvars, typeval *retvar)); +static void find_some_match __ARGS((typeval *argvars, typeval *retvar, int start)); +static void f_strftime __ARGS((typeval *argvars, typeval *retvar)); +static void f_stridx __ARGS((typeval *argvars, typeval *retvar)); +static void f_string __ARGS((typeval *argvars, typeval *retvar)); +static void f_strlen __ARGS((typeval *argvars, typeval *retvar)); +static void f_strpart __ARGS((typeval *argvars, typeval *retvar)); +static void f_strridx __ARGS((typeval *argvars, typeval *retvar)); +static void f_strtrans __ARGS((typeval *argvars, typeval *retvar)); +static void f_synID __ARGS((typeval *argvars, typeval *retvar)); +static void f_synIDattr __ARGS((typeval *argvars, typeval *retvar)); +static void f_synIDtrans __ARGS((typeval *argvars, typeval *retvar)); +static void f_system __ARGS((typeval *argvars, typeval *retvar)); +static void f_submatch __ARGS((typeval *argvars, typeval *retvar)); +static void f_substitute __ARGS((typeval *argvars, typeval *retvar)); +static void f_tempname __ARGS((typeval *argvars, typeval *retvar)); +static void f_tolower __ARGS((typeval *argvars, typeval *retvar)); +static void f_toupper __ARGS((typeval *argvars, typeval *retvar)); +static void f_tr __ARGS((typeval *argvars, typeval *retvar)); +static void f_type __ARGS((typeval *argvars, typeval *retvar)); +static void f_virtcol __ARGS((typeval *argvars, typeval *retvar)); +static void f_visualmode __ARGS((typeval *argvars, typeval *retvar)); +static void f_winbufnr __ARGS((typeval *argvars, typeval *retvar)); +static void f_wincol __ARGS((typeval *argvars, typeval *retvar)); +static void f_winheight __ARGS((typeval *argvars, typeval *retvar)); +static void f_winline __ARGS((typeval *argvars, typeval *retvar)); +static void f_winnr __ARGS((typeval *argvars, typeval *retvar)); +static void f_winrestcmd __ARGS((typeval *argvars, typeval *retvar)); +static void f_winwidth __ARGS((typeval *argvars, typeval *retvar)); +static win_T *find_win_by_nr __ARGS((typeval *vp)); +static pos_T *var2fpos __ARGS((typeval *varp, int lnum)); static int get_env_len __ARGS((char_u **arg)); static int get_id_len __ARGS((char_u **arg)); static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate)); static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end)); static int eval_isnamec __ARGS((int c)); static int find_vim_var __ARGS((char_u *name, int len)); -static int get_var_var __ARGS((char_u *name, int len, VAR retvar)); +static int get_var_vartv __ARGS((char_u *name, int len, typeval *retvar)); static VAR alloc_var __ARGS((void)); -static VAR alloc_string_var __ARGS((char_u *string)); -static void free_var __ARGS((VAR varp)); -static void clear_var __ARGS((VAR varp)); -static long get_var_number __ARGS((VAR varp)); -static linenr_T get_var_lnum __ARGS((VAR argvars)); -static char_u *get_var_string __ARGS((VAR varp)); -static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf)); +static typeval *alloc_vartv __ARGS((void)); +static typeval *alloc_string_vartv __ARGS((char_u *string)); +static void free_vartv __ARGS((typeval *varp)); +static void clear_vartv __ARGS((typeval *varp)); +static long get_vartv_number __ARGS((typeval *varp)); +static linenr_T get_vartv_lnum __ARGS((typeval *argvars)); +static char_u *get_vartv_string __ARGS((typeval *varp)); +static char_u *get_vartv_string_buf __ARGS((typeval *varp, char_u *buf)); static VAR find_var __ARGS((char_u *name, int writing)); static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname)); static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname)); -static void var_free_one __ARGS((VAR v)); +static void clear_var __ARGS((VAR v)); static void list_one_var __ARGS((VAR v, char_u *prefix)); static void list_vim_var __ARGS((int i)); static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); -static void set_var __ARGS((char_u *name, VAR varp, int copy)); -static void copy_var __ARGS((VAR from, VAR to)); +static void set_var __ARGS((char_u *name, typeval *varp, int copy)); +static void copy_vartv __ARGS((typeval *from, typeval *to)); static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); static char_u *trans_function_name __ARGS((char_u **pp, int skip, int internal)); static int eval_fname_script __ARGS((char_u *p)); @@ -427,7 +491,12 @@ static int eval_fname_sid __ARGS((char_u static void list_func_head __ARGS((ufunc_T *fp, int indent)); static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); static ufunc_T *find_func __ARGS((char_u *name)); -static void call_user_func __ARGS((ufunc_T *fp, int argcount, VAR argvars, VAR retvar, linenr_T firstline, linenr_T lastline)); +static int function_exists __ARGS((char_u *name)); +static void call_user_func __ARGS((ufunc_T *fp, int argcount, typeval *argvars, typeval *retvar, linenr_T firstline, linenr_T lastline)); + +#define get_var_string(p) get_vartv_string(&(p)->tv) +#define get_var_string_buf(p, b) get_vartv_string_buf(&(p)->tv, (b)) +#define get_var_number(p) get_vartv_number(&((p)->tv)) /* Magic braces are always enabled, otherwise Vim scripts would not be * portable. */ @@ -446,17 +515,17 @@ set_internal_string_var(name, value) char_u *name; char_u *value; { - char_u *val; - VAR varp; + char_u *val; + typeval *tvp; val = vim_strsave(value); if (val != NULL) { - varp = alloc_string_var(val); - if (varp != NULL) - { - set_var(name, varp, FALSE); - free_var(varp); + tvp = alloc_string_vartv(val); + if (tvp != NULL) + { + set_var(name, tvp, FALSE); + free_vartv(tvp); } } } @@ -575,7 +644,7 @@ eval_to_bool(arg, error, nextcmd, skip) if (!skip) { retval = (get_var_number(&retvar) != 0); - clear_var(&retvar); + clear_vartv(&retvar.tv); } } if (skip) @@ -605,7 +674,7 @@ eval_to_string_skip(arg, nextcmd, skip) else { retval = vim_strsave(get_var_string(&retvar)); - clear_var(&retvar); + clear_vartv(&retvar.tv); } if (skip) --emsg_skip; @@ -621,7 +690,7 @@ eval_to_string_skip(arg, nextcmd, skip) skip_expr(pp) char_u **pp; { - var retvar; + typeval retvar; *pp = skipwhite(*pp); return eval1(pp, &retvar, FALSE); @@ -644,7 +713,7 @@ eval_to_string(arg, nextcmd) else { retval = vim_strsave(get_var_string(&retvar)); - clear_var(&retvar); + clear_vartv(&retvar.tv); } return retval; @@ -680,7 +749,7 @@ eval_to_string_safe(arg, nextcmd) eval_arg_to_string(arg) char_u **arg; { - var retvar; + typeval retvar; char_u *retval; int ret; @@ -691,8 +760,8 @@ eval_arg_to_string(arg) retval = NULL; else { - retval = vim_strsave(get_var_string(&retvar)); - clear_var(&retvar); + retval = vim_strsave(get_vartv_string(&retvar)); + clear_vartv(&retvar); } --emsg_off; @@ -710,7 +779,7 @@ eval_arg_to_string(arg) eval_to_number(expr) char_u *expr; { - var retvar; + typeval retvar; int retval; char_u *p = expr; @@ -720,8 +789,8 @@ eval_to_number(expr) retval = -1; else { - retval = get_var_number(&retvar); - clear_var(&retvar); + retval = get_vartv_number(&retvar); + clear_vartv(&retvar); } --emsg_off; @@ -742,14 +811,14 @@ call_vim_function(func, argc, argv, safe { char_u *retval = NULL; var retvar; - VAR argvars; + typeval *argvars; long n; int len; int i; int doesrange; void *save_funccalp = NULL; - argvars = (VAR)alloc((unsigned)(argc * sizeof(var))); + argvars = (typeval *)alloc((unsigned)(argc * sizeof(typeval))); if (argvars == NULL) return NULL; @@ -758,8 +827,8 @@ call_vim_function(func, argc, argv, safe /* Pass a NULL or empty argument as an empty string */ if (argv[i] == NULL || *argv[i] == NUL) { - argvars[i].var_type = VAR_STRING; - argvars[i].var_val.var_string = (char_u *)""; + argvars[i].v_type = VAR_STRING; + argvars[i].vval.v_string = (char_u *)""; continue; } @@ -767,13 +836,13 @@ call_vim_function(func, argc, argv, safe vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); if (len != 0 && len == (int)STRLEN(argv[i])) { - argvars[i].var_type = VAR_NUMBER; - argvars[i].var_val.var_number = n; + argvars[i].v_type = VAR_NUMBER; + argvars[i].vval.v_number = n; } else { - argvars[i].var_type = VAR_STRING; - argvars[i].var_val.var_string = argv[i]; + argvars[i].v_type = VAR_STRING; + argvars[i].vval.v_string = argv[i]; } } @@ -783,13 +852,13 @@ call_vim_function(func, argc, argv, safe ++sandbox; } - retvar.var_type = VAR_UNKNOWN; /* clear_var() uses this */ - if (call_func(func, (int)STRLEN(func), &retvar, argc, argvars, + retvar.tv.v_type = VAR_UNKNOWN; /* clear_vartv() uses this */ + if (call_func(func, (int)STRLEN(func), &retvar.tv, argc, argvars, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &doesrange, TRUE) == OK) retval = vim_strsave(get_var_string(&retvar)); - clear_var(&retvar); + clear_vartv(&retvar.tv); vim_free(argvars); if (safe) @@ -844,21 +913,21 @@ eval_foldexpr(arg, cp) else { /* If the result is a number, just return the number. */ - if (retvar.var_type == VAR_NUMBER) - retval = retvar.var_val.var_number; - else if (retvar.var_type == VAR_UNKNOWN - || retvar.var_val.var_string == NULL) + if (retvar.tv.v_type == VAR_NUMBER) + retval = retvar.tv.vval.v_number; + else if (retvar.tv.v_type == VAR_UNKNOWN + || retvar.tv.vval.v_string == NULL) retval = 0; else { /* If the result is a string, check if there is a non-digit before * the number. */ - s = retvar.var_val.var_string; + s = retvar.tv.vval.v_string; if (!VIM_ISDIGIT(*s) && *s != '-') *cp = *s++; retval = atol((char *)s); } - clear_var(&retvar); + clear_vartv(&retvar.tv); } --emsg_off; --sandbox; @@ -970,13 +1039,13 @@ ex_let(eap) * List all variables. */ for (i = 0; i < variables.ga_len && !got_int; ++i) - if (VAR_ENTRY(i).var_name != NULL) + if (VAR_ENTRY(i).v_name != NULL) list_one_var(&VAR_ENTRY(i), (char_u *)""); for (i = 0; i < curbuf->b_vars.ga_len && !got_int; ++i) - if (BVAR_ENTRY(i).var_name != NULL) + if (BVAR_ENTRY(i).v_name != NULL) list_one_var(&BVAR_ENTRY(i), (char_u *)"b:"); for (i = 0; i < curwin->w_vars.ga_len && !got_int; ++i) - if (WVAR_ENTRY(i).var_name != NULL) + if (WVAR_ENTRY(i).v_name != NULL) list_one_var(&WVAR_ENTRY(i), (char_u *)"w:"); for (i = 0; i < VV_LEN && !got_int; ++i) if (vimvars[i].type == VAR_NUMBER || vimvars[i].val != NULL) @@ -1103,7 +1172,7 @@ ex_let(eap) if (eap->skip) { if (i != FAIL) - clear_var(&retvar); + clear_vartv(&retvar.tv); --emsg_skip; } else if (i != FAIL) @@ -1214,7 +1283,7 @@ ex_let(eap) } else { - set_var(temp_string, &retvar, TRUE); + set_var(temp_string, &retvar.tv, TRUE); vim_free(temp_string); } } @@ -1223,7 +1292,7 @@ ex_let(eap) { c1 = *p; *p = NUL; - set_var(arg, &retvar, TRUE); + set_var(arg, &retvar.tv, TRUE); *p = c1; /* put char back for error messages */ } } @@ -1233,7 +1302,7 @@ ex_let(eap) EMSG2(_(e_invarg2), arg); } - clear_var(&retvar); + clear_vartv(&retvar.tv); } } } @@ -1350,7 +1419,7 @@ ex_call(eap) name = alias; startarg = arg; - retvar.var_type = VAR_UNKNOWN; /* clear_var() uses this */ + retvar.tv.v_type = VAR_UNKNOWN; /* clear_vartv() uses this */ if (*startarg != '(') { @@ -1379,19 +1448,19 @@ ex_call(eap) curwin->w_cursor.col = 0; } arg = startarg; - if (get_func_var(name, len, &retvar, &arg, + if (get_func_vartv(name, len, &retvar.tv, &arg, eap->line1, eap->line2, &doesrange, !eap->skip) == FAIL) { failed = TRUE; break; } - clear_var(&retvar); + clear_vartv(&retvar.tv); if (doesrange || eap->skip) break; /* Stop when immediately aborting on error, or when an interrupt - * occurred or an exception was thrown but not caught. get_func_var() - * returned OK, so that the check for trailing characters below is - * executed. */ + * occurred or an exception was thrown but not caught. + * get_func_vartv() returned OK, so that the check for trailing + * characters below is executed. */ if (aborting()) break; } @@ -1508,7 +1577,7 @@ do_unlet(name) v = find_var(name, TRUE); if (v != NULL) { - var_free_one(v); + clear_var(v); return OK; } return FAIL; @@ -1524,9 +1593,9 @@ del_menutrans_vars() int i; for (i = 0; i < variables.ga_len; ++i) - if (VAR_ENTRY(i).var_name != NULL - && STRNCMP(VAR_ENTRY(i).var_name, "menutrans_", 10) == 0) - var_free_one(&VAR_ENTRY(i)); + if (VAR_ENTRY(i).v_name != NULL + && STRNCMP(VAR_ENTRY(i).v_name, "menutrans_", 10) == 0) + clear_var(&VAR_ENTRY(i)); } #endif @@ -1592,7 +1661,7 @@ get_user_var_name(xp, idx) gidx = bidx = widx = vidx = 0; if (gidx < variables.ga_len) /* Global variables */ { - while ((name = VAR_ENTRY(gidx++).var_name) == NULL + while ((name = VAR_ENTRY(gidx++).v_name) == NULL && gidx < variables.ga_len) /* skip */; if (name != NULL) @@ -1605,7 +1674,7 @@ get_user_var_name(xp, idx) } if (bidx < curbuf->b_vars.ga_len) /* Current buffer variables */ { - while ((name = BVAR_ENTRY(bidx++).var_name) == NULL + while ((name = BVAR_ENTRY(bidx++).v_name) == NULL && bidx < curbuf->b_vars.ga_len) /* skip */; if (name != NULL) @@ -1618,7 +1687,7 @@ get_user_var_name(xp, idx) } if (widx < curwin->w_vars.ga_len) /* Current window variables */ { - while ((name = WVAR_ENTRY(widx++).var_name) == NULL + while ((name = WVAR_ENTRY(widx++).v_name) == NULL && widx < curwin->w_vars.ga_len) /* skip */; if (name != NULL) @@ -1673,11 +1742,11 @@ eval0(arg, retvar, nextcmd, evaluate) char_u *p; p = skipwhite(arg); - ret = eval1(&p, retvar, evaluate); + ret = eval1(&p, &retvar->tv, evaluate); if (ret == FAIL || !ends_excmd(*p)) { if (ret != FAIL) - clear_var(retvar); + clear_vartv(&retvar->tv); /* * Report the invalid expression unless the expression evaluation has * been cancelled due to an aborting error, an interrupt, or an @@ -1705,11 +1774,11 @@ eval0(arg, retvar, nextcmd, evaluate) static int eval1(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { int result; - var var2; + typeval var2; /* * Get the first variable. @@ -1722,9 +1791,9 @@ eval1(arg, retvar, evaluate) result = FALSE; if (evaluate) { - if (get_var_number(retvar) != 0) + if (get_vartv_number(retvar) != 0) result = TRUE; - clear_var(retvar); + clear_vartv(retvar); } /* @@ -1741,7 +1810,7 @@ eval1(arg, retvar, evaluate) { EMSG(_("E109: Missing ':' after '?'")); if (evaluate && result) - clear_var(retvar); + clear_vartv(retvar); return FAIL; } @@ -1752,7 +1821,7 @@ eval1(arg, retvar, evaluate) if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ { if (evaluate && result) - clear_var(retvar); + clear_vartv(retvar); return FAIL; } if (evaluate && !result) @@ -1774,10 +1843,10 @@ eval1(arg, retvar, evaluate) static int eval2(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; + typeval var2; long result; int first; @@ -1796,9 +1865,9 @@ eval2(arg, retvar, evaluate) { if (evaluate && first) { - if (get_var_number(retvar) != 0) + if (get_vartv_number(retvar) != 0) result = TRUE; - clear_var(retvar); + clear_vartv(retvar); first = FALSE; } @@ -1814,14 +1883,14 @@ eval2(arg, retvar, evaluate) */ if (evaluate && !result) { - if (get_var_number(&var2) != 0) + if (get_vartv_number(&var2) != 0) result = TRUE; - clear_var(&var2); + clear_vartv(&var2); } if (evaluate) { - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = result; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = result; } } @@ -1840,10 +1909,10 @@ eval2(arg, retvar, evaluate) static int eval3(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; + typeval var2; long result; int first; @@ -1862,9 +1931,9 @@ eval3(arg, retvar, evaluate) { if (evaluate && first) { - if (get_var_number(retvar) == 0) + if (get_vartv_number(retvar) == 0) result = FALSE; - clear_var(retvar); + clear_vartv(retvar); first = FALSE; } @@ -1880,14 +1949,14 @@ eval3(arg, retvar, evaluate) */ if (evaluate && result) { - if (get_var_number(&var2) == 0) + if (get_vartv_number(&var2) == 0) result = FALSE; - clear_var(&var2); + clear_vartv(&var2); } if (evaluate) { - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = result; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = result; } } @@ -1913,10 +1982,10 @@ eval3(arg, retvar, evaluate) static int eval4(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; + typeval var2; char_u *p; int i; exptype_T type = TYPE_UNKNOWN; @@ -1992,7 +2061,7 @@ eval4(arg, retvar, evaluate) *arg = skipwhite(p + len); if (eval5(arg, &var2, evaluate) == FAIL) { - clear_var(retvar); + clear_vartv(retvar); return FAIL; } @@ -2002,11 +2071,11 @@ eval4(arg, retvar, evaluate) * If one of the two variables is a number, compare as a number. * When using "=~" or "!~", always compare as string. */ - if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER) + if ((retvar->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) && type != TYPE_MATCH && type != TYPE_NOMATCH) { - n1 = get_var_number(retvar); - n2 = get_var_number(&var2); + n1 = get_vartv_number(retvar); + n2 = get_vartv_number(&var2); switch (type) { case TYPE_EQUAL: n1 = (n1 == n2); break; @@ -2022,8 +2091,8 @@ eval4(arg, retvar, evaluate) } else { - s1 = get_var_string_buf(retvar, buf1); - s2 = get_var_string_buf(&var2, buf2); + s1 = get_vartv_string_buf(retvar, buf1); + s2 = get_vartv_string_buf(&var2, buf2); if (type != TYPE_MATCH && type != TYPE_NOMATCH) i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); else @@ -2059,10 +2128,10 @@ eval4(arg, retvar, evaluate) case TYPE_UNKNOWN: break; /* avoid gcc warning */ } } - clear_var(retvar); - clear_var(&var2); - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = n1; + clear_vartv(retvar); + clear_vartv(&var2); + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = n1; } } @@ -2083,10 +2152,10 @@ eval4(arg, retvar, evaluate) static int eval5(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; + typeval var2; int op; long n1, n2; char_u *s1, *s2; @@ -2114,7 +2183,7 @@ eval5(arg, retvar, evaluate) *arg = skipwhite(*arg + 1); if (eval6(arg, &var2, evaluate) == FAIL) { - clear_var(retvar); + clear_vartv(retvar); return FAIL; } @@ -2125,8 +2194,8 @@ eval5(arg, retvar, evaluate) */ if (op == '.') { - s1 = get_var_string_buf(retvar, buf1); - s2 = get_var_string_buf(&var2, buf2); + s1 = get_vartv_string_buf(retvar, buf1); + s2 = get_vartv_string_buf(&var2, buf2); op = (int)STRLEN(s1); p = alloc((unsigned)(op + STRLEN(s2) + 1)); if (p != NULL) @@ -2134,23 +2203,23 @@ eval5(arg, retvar, evaluate) STRCPY(p, s1); STRCPY(p + op, s2); } - clear_var(retvar); - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = p; + clear_vartv(retvar); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = p; } else { - n1 = get_var_number(retvar); - n2 = get_var_number(&var2); - clear_var(retvar); + n1 = get_vartv_number(retvar); + n2 = get_vartv_number(&var2); + clear_vartv(retvar); if (op == '+') n1 = n1 + n2; else n1 = n1 - n2; - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = n1; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = n1; } - clear_var(&var2); + clear_vartv(&var2); } } return OK; @@ -2170,10 +2239,10 @@ eval5(arg, retvar, evaluate) static int eval6(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; + typeval var2; int op; long n1, n2; @@ -2194,8 +2263,8 @@ eval6(arg, retvar, evaluate) if (evaluate) { - n1 = get_var_number(retvar); - clear_var(retvar); + n1 = get_vartv_number(retvar); + clear_vartv(retvar); } else n1 = 0; @@ -2209,8 +2278,8 @@ eval6(arg, retvar, evaluate) if (evaluate) { - n2 = get_var_number(&var2); - clear_var(&var2); + n2 = get_vartv_number(&var2); + clear_vartv(&var2); /* * Compute the result. @@ -2231,8 +2300,8 @@ eval6(arg, retvar, evaluate) else n1 = n1 % n2; } - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = n1; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = n1; } } @@ -2265,10 +2334,9 @@ eval6(arg, retvar, evaluate) static int eval7(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { - var var2; long n; int len; char_u *s; @@ -2278,10 +2346,10 @@ eval7(arg, retvar, evaluate) char_u *alias; /* - * Initialise variable so that clear_var() can't mistake this for a string - * and free a string that isn't there. + * Initialise variable so that clear_vartv() can't mistake this for a + * string and free a string that isn't there. */ - retvar->var_type = VAR_UNKNOWN; + retvar->v_type = VAR_UNKNOWN; /* * Skip '!' and '-' characters. They are handled later. @@ -2310,33 +2378,39 @@ eval7(arg, retvar, evaluate) *arg += len; if (evaluate) { - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = n; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = n; } break; /* * String constant: "string". */ - case '"': ret = get_string_var(arg, retvar, evaluate); + case '"': ret = get_string_vartv(arg, retvar, evaluate); break; /* * Literal string constant: 'string'. */ - case '\'': ret = get_lit_string_var(arg, retvar, evaluate); + case '\'': ret = get_lit_string_vartv(arg, retvar, evaluate); + break; + + /* + * List: [expr, expr] + */ + case '[': ret = get_list_vartv(arg, retvar, evaluate); break; /* * Option value: &name */ - case '&': ret = get_option_var(arg, retvar, evaluate); + case '&': ret = get_option_vartv(arg, retvar, evaluate); break; /* * Environment variable: $VAR. */ - case '$': ret = get_env_var(arg, retvar, evaluate); + case '$': ret = get_env_vartv(arg, retvar, evaluate); break; /* @@ -2345,8 +2419,8 @@ eval7(arg, retvar, evaluate) case '@': ++*arg; if (evaluate) { - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = get_reg_contents(**arg, FALSE); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = get_reg_contents(**arg, FALSE); } if (**arg != NUL) ++*arg; @@ -2362,7 +2436,7 @@ eval7(arg, retvar, evaluate) else if (ret == OK) { EMSG(_("E110: Missing ')'")); - clear_var(retvar); + clear_vartv(retvar); ret = FAIL; } break; @@ -2381,7 +2455,12 @@ eval7(arg, retvar, evaluate) { if (**arg == '(') /* recursive! */ { - ret = get_func_var(s, len, retvar, arg, + /* If "s" is the name of a variable of type VAR_FUNC + * use its contents. */ + s = deref_func_name(s, &len); + + /* Invoke the function. */ + ret = get_func_vartv(s, len, retvar, arg, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &len, evaluate); /* Stop the expression evaluation when immediately @@ -2390,12 +2469,12 @@ eval7(arg, retvar, evaluate) if (aborting()) { if (ret == OK) - clear_var(retvar); + clear_vartv(retvar); ret = FAIL; } } else if (evaluate) - ret = get_var_var(s, len, retvar); + ret = get_var_vartv(s, len, retvar); } if (alias != NULL) @@ -2406,48 +2485,15 @@ eval7(arg, retvar, evaluate) *arg = skipwhite(*arg); /* - * Handle expr[expr] subscript. + * Handle expr[expr] and expr[expr:expr] subscript. */ - if (**arg == '[' && ret == OK) - { - /* - * Get the variable from inside the []. - */ - *arg = skipwhite(*arg + 1); - if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ - { - clear_var(retvar); - return FAIL; - } - - /* Check for the ']'. */ - if (**arg != ']') - { - EMSG(_("E111: Missing ']'")); - clear_var(retvar); - clear_var(&var2); + while (**arg == '[' && ret == OK) + { + if (eval_index(arg, retvar, evaluate) == FAIL) + { + clear_vartv(retvar); return FAIL; } - - if (evaluate) - { - n = get_var_number(&var2); - clear_var(&var2); - - /* - * The resulting variable is a string of a single character. - * If the index is too big or negative, the result is empty. - */ - s = get_var_string(retvar); - if (n >= (long)STRLEN(s) || n < 0) - s = NULL; - else - s = vim_strnsave(s + n, 1); - clear_var(retvar); - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = s; - } - *arg = skipwhite(*arg + 1); /* skip the ']' */ } /* @@ -2455,7 +2501,7 @@ eval7(arg, retvar, evaluate) */ if (ret == OK && evaluate && end_leader > start_leader) { - val = get_var_number(retvar); + val = get_vartv_number(retvar); while (end_leader > start_leader) { --end_leader; @@ -2464,24 +2510,198 @@ eval7(arg, retvar, evaluate) else if (*end_leader == '-') val = -val; } - clear_var(retvar); - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = val; + clear_vartv(retvar); + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = val; } return ret; } /* + * Evaluate an "[expr]" or "[expr:expr]" index. + * "*arg" points to the '['. + * Returns FAIL or OK. "*arg" is advanced to after the ']'. + */ + static int +eval_index(arg, retvar, evaluate) + char_u **arg; + typeval *retvar; + int evaluate; +{ + int empty1 = FALSE, empty2 = FALSE; + typeval var1, var2; + long n1, n2 = 0; + long len; + int range; + char_u *s; + + if (retvar->v_type == VAR_FUNC) + { + EMSG(_("E999: Cannot index a Funcref")); + return FAIL; + } + + /* + * Get the (first) variable from inside the []. + */ + *arg = skipwhite(*arg + 1); + if (**arg == ':') + empty1 = TRUE; + else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ + return FAIL; + + /* + * Get the second variable from inside the [:]. + */ + if (**arg == ':') + { + range = TRUE; + *arg = skipwhite(*arg + 1); + if (**arg == ']') + empty2 = TRUE; + else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ + { + clear_vartv(&var1); + return FAIL; + } + } + else + range = FALSE; + + /* Check for the ']'. */ + if (**arg != ']') + { + EMSG(_("E111: Missing ']'")); + clear_vartv(&var1); + if (range) + clear_vartv(&var2); + return FAIL; + } + + if (evaluate) + { + if (empty1) + n1 = 0; + else + { + n1 = get_vartv_number(&var1); + clear_vartv(&var1); + } + if (range) + { + if (empty2) + n2 = -1; + else + { + n2 = get_vartv_number(&var2); + clear_vartv(&var2); + } + } + + switch (retvar->v_type) + { + case VAR_NUMBER: + case VAR_STRING: + s = get_vartv_string(retvar); + len = (long)STRLEN(s); + if (range) + { + /* The resulting variable is a substring. If the indexes + * are out of range the result is empty. */ + if (n1 < 0) + { + n1 = len + n1; + if (n1 < 0) + n1 = 0; + } + if (n2 < 0) + n2 = len + n2; + else if (n2 >= len) + n2 = len; + if (n1 >= len || n2 < 0 || n1 > n2) + s = NULL; + else + s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); + } + else + { + /* The resulting variable is a string of a single + * character. If the index is too big or negative the + * result is empty. */ + if (n1 >= len || n1 < 0) + s = NULL; + else + s = vim_strnsave(s + n1, 1); + } + clear_vartv(retvar); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = s; + break; + + case VAR_LIST: + len = list_len(retvar->vval.v_list); + if (n1 < 0) + n1 = len + n1; + if (!empty1 && (n1 < 0 || n1 >= len)) + { + EMSGN(_(e_listidx), n1); + return FAIL; + } + if (range) + { + listvar *l; + listitem *item; + + if (n2 < 0) + n2 = len + n2; + if (!empty2 && (n2 < 0 || n2 >= len || n2 < n1)) + { + EMSGN(_(e_listidx), n2); + return FAIL; + } + l = list_alloc(); + if (l == NULL) + return FAIL; + for (item = list_find(retvar->vval.v_list, n1); + n1 <= n2; ++n1) + { + if (list_append_tv(l, &item->li_tv) == FAIL) + { + list_free(l); + return FAIL; + } + item = item->li_next; + } + clear_vartv(retvar); + retvar->v_type = VAR_LIST; + retvar->vval.v_list = l; + } + else + { + copy_vartv(&list_find(retvar->vval.v_list, n1)->li_tv, + &var1); + clear_vartv(retvar); + *retvar = var1; + } + break; + } + } + + *arg = skipwhite(*arg + 1); /* skip the ']' */ + return OK; +} + +/* * Get an option value. * "arg" points to the '&' or '+' before the option name. * "arg" is advanced to character after the option name. * Return OK or FAIL. */ static int -get_option_var(arg, retvar, evaluate) +get_option_vartv(arg, retvar, evaluate) char_u **arg; - VAR retvar; /* when NULL, only check if option exists */ + typeval *retvar; /* when NULL, only check if option exists */ int evaluate; { char_u *option_end; @@ -2525,23 +2745,23 @@ get_option_var(arg, retvar, evaluate) { if (opt_type == -2) /* hidden string option */ { - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; } else if (opt_type == -1) /* hidden number option */ { - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = 0; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = 0; } else if (opt_type == 1) /* number option */ { - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = numval; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = numval; } else /* string option */ { - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = stringval; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = stringval; } } else if (working && (opt_type == -2 || opt_type == -1)) @@ -2558,9 +2778,9 @@ get_option_var(arg, retvar, evaluate) * Return OK or FAIL. */ static int -get_string_var(arg, retvar, evaluate) +get_string_vartv(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { char_u *p; @@ -2703,8 +2923,8 @@ get_string_var(arg, retvar, evaluate) name[i] = NUL; *arg = p + 1; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = name; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = name; return OK; } @@ -2714,9 +2934,9 @@ get_string_var(arg, retvar, evaluate) * Return OK or FAIL. */ static int -get_lit_string_var(arg, retvar, evaluate) +get_lit_string_vartv(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { char_u *p; @@ -2741,8 +2961,8 @@ get_lit_string_var(arg, retvar, evaluate if (name == NULL) return FAIL; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = name; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = name; } *arg = p + 1; @@ -2751,15 +2971,375 @@ get_lit_string_var(arg, retvar, evaluate } /* + * Allocate a variable for a List and fill it from "*arg". + * Return OK or FAIL. + */ + static int +get_list_vartv(arg, retvar, evaluate) + char_u **arg; + typeval *retvar; + int evaluate; +{ + listvar *l = NULL; + typeval tv; + listitem *item; + + if (evaluate) + { + l = list_alloc(); + if (l == NULL) + return FAIL; + } + + *arg = skipwhite(*arg + 1); + while (**arg != ']' && **arg != NUL) + { + if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ + goto failret; + if (evaluate) + { + item = listitem_alloc(); + if (item != NULL) + { + item->li_tv = tv; + list_append(l, item); + } + } + + if (**arg == ']') + break; + if (**arg != ',') + { + EMSG2(_("E999: Missing comma in list: %s"), *arg); + goto failret; + } + *arg = skipwhite(*arg + 1); + } + + if (**arg != ']') + { + EMSG2(_("E999: Missing end of list ']': %s"), *arg); +failret: + if (evaluate) + list_free(l); + return FAIL; + } + + *arg = skipwhite(*arg + 1); + if (evaluate) + { + retvar->v_type = VAR_LIST; + retvar->vval.v_list = l; + ++l->lv_refcount; + } + + return OK; +} + +/* + * Allocate an empty header for a list. + */ + static listvar * +list_alloc() +{ + return (listvar *)alloc_clear(sizeof(listvar)); +} + +/* + * Unreference a list: decrement the reference count and free it when it + * becomes zero. + */ + static void +list_unref(l) + listvar *l; +{ + if (l != NULL && --l->lv_refcount <= 0) + list_free(l); +} + +/* + * Free a list, including all items it points to. + * Ignores the reference count. + */ + static void +list_free(l) + listvar *l; +{ + listitem *item; + listitem *next; + + for (item = l->lv_first; item != NULL; item = next) + { + next = item->li_next; + listitem_free(item); + } + vim_free(l); +} + +/* + * Allocate a list item. + */ + static listitem * +listitem_alloc() +{ + return (listitem *)alloc(sizeof(listitem)); +} + +/* + * Free a list item. Also clears the value; + */ + static void +listitem_free(item) + listitem *item; +{ + clear_vartv(&item->li_tv); + vim_free(item); +} + +/* + * Get the number of items in a list. + */ + static long +list_len(l) + listvar *l; +{ + listitem *item; + long len = 0; + + if (l == NULL) + return 0L; + for (item = l->lv_first; item != NULL; item = item->li_next) + ++len; + return len; +} + +/* + * Locate item with index "n" in list "l" and return it. + * A negative index is counted from the end; -1 is the last item. + * Returns NULL when "n" is out of range. + */ + static listitem * +list_find(l, n) + listvar *l; + long n; +{ + listitem *item; + long idx; + + if (l == NULL) + return NULL; + if (n < 0) + { + idx = -1; /* search from the end */ + for (item = l->lv_last; item != NULL && idx > n; item = item->li_prev) + --idx; + } + else + { + idx = 0; /* search from the start */ + for (item = l->lv_first; item != NULL && idx < n; item = item->li_next) + ++idx; + } + if (idx != n) + return NULL; + return item; +} + +/* + * Append item "item" to the end of list "l". + */ + static void +list_append(l, item) + listvar *l; + listitem *item; +{ + if (l->lv_last == NULL) + { + /* empty list */ + l->lv_first = item; + l->lv_last = item; + item->li_prev = NULL; + } + else + { + l->lv_last->li_next = item; + item->li_prev = l->lv_last; + l->lv_last = item; + } + item->li_next = NULL; +} + +/* + * Append typeval "tv" to the end of list "l". + */ + static int +list_append_tv(l, tv) + listvar *l; + typeval *tv; +{ + listitem *ni = listitem_alloc(); + + if (ni == NULL) + return FAIL; + copy_vartv(tv, &ni->li_tv); + list_append(l, ni); + return OK; +} + +/* + * Make a copy of list "l". Shallow if "deep" is FALSE. + * The refcount of the new list is set to 1. + * Returns NULL when out of memory. + */ + static listvar * +list_copy(orig, deep) + listvar *orig; + int deep; +{ + listvar *copy; + listitem *item; + listitem *ni; + static int recurse = 0; + + if (orig == NULL) + return NULL; + if (recurse >= VAR_LIST_MAXNEST) + { + EMSG(_("E999: List nested too deep for making a copy")); + return NULL; + } + ++recurse; + + copy = list_alloc(); + if (copy != NULL) + { + for (item = orig->lv_first; item != NULL; item = item->li_next) + { + ni = listitem_alloc(); + if (ni == NULL) + break; + if (deep && item->li_tv.v_type == VAR_LIST) + { + ni->li_tv.v_type = VAR_LIST; + ni->li_tv.vval.v_list = list_copy(item->li_tv.vval.v_list, + TRUE); + if (ni->li_tv.vval.v_list == NULL) + { + vim_free(ni); + break; + } + } + else + copy_vartv(&item->li_tv, &ni->li_tv); + list_append(copy, ni); + } + ++copy->lv_refcount; + } + + --recurse; + return copy; +} + +/* + * Remove item with index "n" from list "l" and return it. + * Returns NULL when "n" is out of range. + */ + static listitem * +list_getrem(l, n) + listvar *l; + long n; +{ + listitem *item; + + item = list_find(l, n); + if (item != NULL) + { + if (item->li_next == NULL) + l->lv_last = item->li_prev; + else + item->li_next->li_prev = item->li_prev; + if (item->li_prev == NULL) + l->lv_first = item->li_next; + else + item->li_prev->li_next = item->li_next; + } + return item; +} + +/* + * Return an allocated string with the string representation of a list. + * May return NULL. + */ + static char_u * +list2string(tv) + typeval *tv; +{ + garray_T ga; + listitem *item; + int first = TRUE; + char_u *tofree; + char_u *s; + + if (tv->vval.v_list == NULL) + return NULL; + ga_init2(&ga, (int)sizeof(char), 80); + ga_append(&ga, '['); + + for (item = tv->vval.v_list->lv_first; item != NULL; item = item->li_next) + { + if (first) + first = FALSE; + else + ga_concat(&ga, (char_u *)", "); + + s = tv2string(&item->li_tv, &tofree); + if (s != NULL) + ga_concat(&ga, s); + vim_free(tofree); + } + + ga_append(&ga, ']'); + ga_append(&ga, NUL); + return (char_u *)ga.ga_data; +} + +/* + * Return a string with the string representation of a variable. + * If the memory is allocated "tofree" is set to it, otherwise NULL. + * Can only be used once before the value is used, it may call + * get_var_string(). + * May return NULL; + */ + static char_u * +tv2string(tv, tofree) + typeval *tv; + char_u **tofree; +{ + switch (tv->v_type) + { + case VAR_FUNC: + *tofree = NULL; + return tv->vval.v_string; + case VAR_LIST: + *tofree = list2string(tv); + return *tofree; + default: + break; + } + *tofree = NULL; + return get_vartv_string(tv); +} + +/* * Get the value of an environment variable. * "arg" is pointing to the '$'. It is advanced to after the name. * If the environment variable was not set, silently assume it is empty. * Always return OK. */ static int -get_env_var(arg, retvar, evaluate) +get_env_vartv(arg, retvar, evaluate) char_u **arg; - VAR retvar; + typeval *retvar; int evaluate; { char_u *string = NULL; @@ -2792,8 +3372,8 @@ get_env_var(arg, retvar, evaluate) } name[len] = cc; } - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = string; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = string; } return OK; @@ -2808,7 +3388,8 @@ static struct fst char *f_name; /* function name */ char f_min_argc; /* minimal number of arguments */ char f_max_argc; /* maximal number of arguments */ - void (*f_func) __ARGS((VAR args, VAR rvar)); /* impl. function */ + void (*f_func) __ARGS((typeval *args, typeval *rvar)); + /* implemenation of function */ } functions[] = { {"append", 2, 2, f_append}, @@ -2832,8 +3413,10 @@ static struct fst {"cindent", 1, 1, f_cindent}, {"col", 1, 1, f_col}, {"confirm", 1, 4, f_confirm}, + {"copy", 1, 1, f_copy}, {"cscope_connection",0,3, f_cscope_connection}, {"cursor", 2, 2, f_cursor}, + {"deepcopy", 1, 1, f_deepcopy}, {"delete", 1, 1, f_delete}, {"did_filetype", 0, 0, f_did_filetype}, {"diff_filler", 1, 1, f_diff_filler}, @@ -2855,6 +3438,7 @@ static struct fst {"foldtext", 0, 0, f_foldtext}, {"foldtextresult", 1, 1, f_foldtextresult}, {"foreground", 0, 0, f_foreground}, + {"function", 1, 1, f_function}, {"getbufvar", 2, 2, f_getbufvar}, {"getchar", 0, 1, f_getchar}, {"getcharmod", 0, 0, f_getcharmod}, @@ -2892,8 +3476,10 @@ static struct fst {"inputrestore", 0, 0, f_inputrestore}, {"inputsave", 0, 0, f_inputsave}, {"inputsecret", 1, 2, f_inputsecret}, + {"insert", 2, 3, f_insert}, {"isdirectory", 1, 1, f_isdirectory}, {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ + {"len", 1, 1, f_len}, {"libcall", 3, 3, f_libcall}, {"libcallnr", 3, 3, f_libcallnr}, {"line", 1, 1, f_line}, @@ -2914,6 +3500,7 @@ static struct fst {"remote_peek", 1, 2, f_remote_peek}, {"remote_read", 1, 1, f_remote_read}, {"remote_send", 2, 3, f_remote_send}, + {"remove", 2, 2, f_remove}, {"rename", 2, 2, f_rename}, {"repeat", 2, 2, f_repeat}, {"resolve", 1, 1, f_resolve}, @@ -2931,6 +3518,7 @@ static struct fst {"strftime", 1, 2, f_strftime}, #endif {"stridx", 2, 2, f_stridx}, + {"string", 1, 1, f_string}, {"strlen", 1, 1, f_strlen}, {"strpart", 2, 3, f_strpart}, {"strridx", 2, 2, f_strridx}, @@ -3048,14 +3636,44 @@ find_internal_func(name) } /* + * Check if "name" is a variable of type VAR_FUNC. If so, return the function + * name it contains, otherwise return "name". + */ + static char_u * +deref_func_name(name, lenp) + char_u *name; + int *lenp; +{ + VAR v; + int cc; + + cc = name[*lenp]; + name[*lenp] = NUL; + v = find_var(name, FALSE); + name[*lenp] = cc; + if (v != NULL && v->tv.v_type == VAR_FUNC) + { + if (v->tv.vval.v_string == NULL) + { + *lenp = 0; + return (char_u *)""; /* just in case */ + } + *lenp = STRLEN(v->tv.vval.v_string); + return v->tv.vval.v_string; + } + + return name; +} + +/* * Allocate a variable for the result of a function. * Return OK or FAIL. */ static int -get_func_var(name, len, retvar, arg, firstline, lastline, doesrange, evaluate) +get_func_vartv(name, len, retvar, arg, firstline, lastline, doesrange, evaluate) char_u *name; /* name of the function */ int len; /* length of "name" */ - VAR retvar; + typeval *retvar; char_u **arg; /* argument, pointing to the '(' */ linenr_T firstline; /* first line of range */ linenr_T lastline; /* last line of range */ @@ -3065,7 +3683,7 @@ get_func_var(name, len, retvar, arg, fir char_u *argp; int ret = OK; #define MAX_FUNC_ARGS 20 - var argvars[MAX_FUNC_ARGS]; /* vars for arguments */ + typeval argvars[MAX_FUNC_ARGS]; /* vars for arguments */ int argcount = 0; /* number of arguments found */ /* @@ -3077,7 +3695,6 @@ get_func_var(name, len, retvar, arg, fir argp = skipwhite(argp + 1); /* skip the '(' or ',' */ if (*argp == ')' || *argp == ',' || *argp == NUL) break; - argvars[argcount].var_name = NULL; /* the name is not stored */ if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) { ret = FAIL; @@ -3099,7 +3716,7 @@ get_func_var(name, len, retvar, arg, fir EMSG2(_("E116: Invalid arguments for function %s"), name); while (--argcount >= 0) - clear_var(&argvars[argcount]); + clear_vartv(&argvars[argcount]); *arg = skipwhite(argp); return ret; @@ -3115,9 +3732,9 @@ call_func(name, len, retvar, argcount, a doesrange, evaluate) char_u *name; /* name of the function */ int len; /* length of "name" */ - VAR retvar; /* return value goes here */ + typeval *retvar; /* return value goes here */ int argcount; /* number of "argvars" */ - VAR argvars; /* vars for arguments */ + typeval *argvars; /* vars for arguments */ linenr_T firstline; /* first line of range */ linenr_T lastline; /* last line of range */ int *doesrange; /* return: function handled range */ @@ -3195,7 +3812,7 @@ call_func(name, len, retvar, argcount, a /* execute the function if no errors detected and executing */ if (evaluate && error == ERROR_NONE) { - retvar->var_type = VAR_NUMBER; /* default is number retvar */ + retvar->v_type = VAR_NUMBER; /* default is number retvar */ error = ERROR_UNKNOWN; if (!ASCII_ISLOWER(fname[0])) @@ -3257,7 +3874,7 @@ call_func(name, len, retvar, argcount, a error = ERROR_TOOMANY; else { - argvars[argcount].var_type = VAR_UNKNOWN; + argvars[argcount].v_type = VAR_UNKNOWN; functions[i].f_func(argvars, retvar); error = ERROR_NONE; } @@ -3298,26 +3915,35 @@ call_func(name, len, retvar, argcount, a /* * "append(lnum, string)" function + * or "append(list, item)" function */ static void f_append(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { long lnum; - lnum = get_var_lnum(argvars); - retvar->var_val.var_number = 1; /* Default: Failed */ - - if (lnum >= 0 - && lnum <= curbuf->b_ml.ml_line_count - && u_save(lnum, lnum + 1) == OK) - { - ml_append(lnum, get_var_string(&argvars[1]), (colnr_T)0, FALSE); - if (curwin->w_cursor.lnum > lnum) - ++curwin->w_cursor.lnum; - appended_lines_mark(lnum, 1L); - retvar->var_val.var_number = 0; + retvar->vval.v_number = 1; /* Default: Failed */ + if (argvars[0].v_type == VAR_LIST) + { + if (argvars[0].vval.v_list != NULL + && list_append_tv(argvars[0].vval.v_list, &argvars[1]) == OK) + copy_vartv(&argvars[0], retvar); + } + else + { + lnum = get_vartv_lnum(argvars); + if (lnum >= 0 + && lnum <= curbuf->b_ml.ml_line_count + && u_save(lnum, lnum + 1) == OK) + { + ml_append(lnum, get_vartv_string(&argvars[1]), (colnr_T)0, FALSE); + if (curwin->w_cursor.lnum > lnum) + ++curwin->w_cursor.lnum; + appended_lines_mark(lnum, 1L); + retvar->vval.v_number = 0; + } } } @@ -3327,10 +3953,10 @@ f_append(argvars, retvar) /* ARGSUSED */ static void f_argc(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = ARGCOUNT; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = ARGCOUNT; } /* @@ -3339,10 +3965,10 @@ f_argc(argvars, retvar) /* ARGSUSED */ static void f_argidx(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = curwin->w_arg_idx; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = curwin->w_arg_idx; } /* @@ -3350,17 +3976,17 @@ f_argidx(argvars, retvar) */ static void f_argv(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int idx; - idx = get_var_number(&argvars[0]); + idx = get_vartv_number(&argvars[0]); if (idx >= 0 && idx < ARGCOUNT) - retvar->var_val.var_string = vim_strsave(alist_name(&ARGLIST[idx])); - else - retvar->var_val.var_string = NULL; - retvar->var_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); + else + retvar->vval.v_string = NULL; + retvar->v_type = VAR_STRING; } /* @@ -3369,8 +3995,8 @@ f_argv(argvars, retvar) /* ARGSUSED */ static void f_browse(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_BROWSE int save; @@ -3380,18 +4006,18 @@ f_browse(argvars, retvar) char_u buf[NUMBUFLEN]; char_u buf2[NUMBUFLEN]; - save = get_var_number(&argvars[0]); - title = get_var_string(&argvars[1]); - initdir = get_var_string_buf(&argvars[2], buf); - defname = get_var_string_buf(&argvars[3], buf2); - - retvar->var_val.var_string = + save = get_vartv_number(&argvars[0]); + title = get_vartv_string(&argvars[1]); + initdir = get_vartv_string_buf(&argvars[2], buf); + defname = get_vartv_string_buf(&argvars[3], buf2); + + retvar->vval.v_string = do_browse(save ? BROWSE_SAVE : 0, title, defname, NULL, initdir, NULL, curbuf); #else - retvar->var_val.var_string = NULL; -#endif - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; +#endif + retvar->v_type = VAR_STRING; } /* @@ -3400,23 +4026,23 @@ f_browse(argvars, retvar) /* ARGSUSED */ static void f_browsedir(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_BROWSE char_u *title; char_u *initdir; char_u buf[NUMBUFLEN]; - title = get_var_string(&argvars[0]); - initdir = get_var_string_buf(&argvars[1], buf); - - retvar->var_val.var_string = do_browse(BROWSE_DIR, + title = get_vartv_string(&argvars[0]); + initdir = get_vartv_string_buf(&argvars[1], buf); + + retvar->vval.v_string = do_browse(BROWSE_DIR, title, NULL, NULL, initdir, NULL, curbuf); #else - retvar->var_val.var_string = NULL; -#endif - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; +#endif + retvar->v_type = VAR_STRING; } /* @@ -3424,15 +4050,15 @@ f_browsedir(argvars, retvar) */ static buf_T * find_buffer(avar) - VAR avar; + typeval *avar; { buf_T *buf = NULL; - if (avar->var_type == VAR_NUMBER) - buf = buflist_findnr((int)avar->var_val.var_number); - else if (avar->var_val.var_string != NULL) - { - buf = buflist_findname_exp(avar->var_val.var_string); + if (avar->v_type == VAR_NUMBER) + buf = buflist_findnr((int)avar->vval.v_number); + else if (avar->vval.v_string != NULL) + { + buf = buflist_findname_exp(avar->vval.v_string); if (buf == NULL) { /* No full path name match, try a match with a URL or a "nofile" @@ -3444,7 +4070,7 @@ find_buffer(avar) || bt_nofile(buf) #endif ) - && STRCMP(buf->b_fname, avar->var_val.var_string) == 0) + && STRCMP(buf->b_fname, avar->vval.v_string) == 0) break; } } @@ -3456,10 +4082,10 @@ find_buffer(avar) */ static void f_bufexists(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = (find_buffer(&argvars[0]) != NULL); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = (find_buffer(&argvars[0]) != NULL); } /* @@ -3467,13 +4093,13 @@ f_bufexists(argvars, retvar) */ static void f_buflisted(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; buf = find_buffer(&argvars[0]); - retvar->var_val.var_number = (buf != NULL && buf->b_p_bl); + retvar->vval.v_number = (buf != NULL && buf->b_p_bl); } /* @@ -3481,29 +4107,29 @@ f_buflisted(argvars, retvar) */ static void f_bufloaded(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; buf = find_buffer(&argvars[0]); - retvar->var_val.var_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); + retvar->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); } /* * Get buffer by number or pattern. */ static buf_T * -get_buf_var(avar) - VAR avar; -{ - char_u *name = avar->var_val.var_string; +get_buf_vartv(avar) + typeval *avar; +{ + char_u *name = avar->vval.v_string; int save_magic; char_u *save_cpo; buf_T *buf; - if (avar->var_type == VAR_NUMBER) - return buflist_findnr((int)avar->var_val.var_number); + if (avar->v_type == VAR_NUMBER) + return buflist_findnr((int)avar->vval.v_number); if (name == NULL || *name == NUL) return curbuf; if (name[0] == '$' && name[1] == NUL) @@ -3533,18 +4159,18 @@ get_buf_var(avar) */ static void f_bufname(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; ++emsg_off; - buf = get_buf_var(&argvars[0]); - retvar->var_type = VAR_STRING; + buf = get_buf_vartv(&argvars[0]); + retvar->v_type = VAR_STRING; if (buf != NULL && buf->b_fname != NULL) - retvar->var_val.var_string = vim_strsave(buf->b_fname); - else - retvar->var_val.var_string = NULL; + retvar->vval.v_string = vim_strsave(buf->b_fname); + else + retvar->vval.v_string = NULL; --emsg_off; } @@ -3553,17 +4179,17 @@ f_bufname(argvars, retvar) */ static void f_bufnr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; ++emsg_off; - buf = get_buf_var(&argvars[0]); + buf = get_buf_vartv(&argvars[0]); if (buf != NULL) - retvar->var_val.var_number = buf->b_fnum; - else - retvar->var_val.var_number = -1; + retvar->vval.v_number = buf->b_fnum; + else + retvar->vval.v_number = -1; --emsg_off; } @@ -3572,8 +4198,8 @@ f_bufnr(argvars, retvar) */ static void f_bufwinnr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_WINDOWS win_T *wp; @@ -3582,7 +4208,7 @@ f_bufwinnr(argvars, retvar) buf_T *buf; ++emsg_off; - buf = get_buf_var(&argvars[0]); + buf = get_buf_vartv(&argvars[0]); #ifdef FEAT_WINDOWS for (wp = firstwin; wp; wp = wp->w_next) { @@ -3590,9 +4216,9 @@ f_bufwinnr(argvars, retvar) if (wp->w_buffer == buf) break; } - retvar->var_val.var_number = (wp != NULL ? winnr : -1); + retvar->vval.v_number = (wp != NULL ? winnr : -1); #else - retvar->var_val.var_number = (curwin->w_buffer == buf ? 1 : -1); + retvar->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); #endif --emsg_off; } @@ -3603,19 +4229,19 @@ f_bufwinnr(argvars, retvar) /*ARGSUSED*/ static void f_byte2line(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifndef FEAT_BYTEOFF - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; #else long boff = 0; - boff = get_var_number(&argvars[0]) - 1; + boff = get_vartv_number(&argvars[0]) - 1; if (boff < 0) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = ml_find_line_or_offset(curbuf, + retvar->vval.v_number = -1; + else + retvar->vval.v_number = ml_find_line_or_offset(curbuf, (linenr_T)0, &boff); #endif } @@ -3626,8 +4252,8 @@ f_byte2line(argvars, retvar) /*ARGSUSED*/ static void f_byteidx(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_MBYTE char_u *t; @@ -3635,9 +4261,9 @@ f_byteidx(argvars, retvar) char_u *str; long idx; - str = get_var_string(&argvars[0]); - idx = get_var_number(&argvars[1]); - retvar->var_val.var_number = -1; + str = get_vartv_string(&argvars[0]); + idx = get_vartv_number(&argvars[1]); + retvar->vval.v_number = -1; if (idx < 0) return; @@ -3649,10 +4275,10 @@ f_byteidx(argvars, retvar) return; t += mb_ptr2len_check(t); } - retvar->var_val.var_number = t - str; + retvar->vval.v_number = t - str; #else if (idx <= STRLEN(str)) - retvar->var_val.var_number = idx; + retvar->vval.v_number = idx; #endif } @@ -3661,16 +4287,16 @@ f_byteidx(argvars, retvar) */ static void f_char2nr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_MBYTE if (has_mbyte) - retvar->var_val.var_number = - (*mb_ptr2char)(get_var_string(&argvars[0])); - else -#endif - retvar->var_val.var_number = get_var_string(&argvars[0])[0]; + retvar->vval.v_number = + (*mb_ptr2char)(get_vartv_string(&argvars[0])); + else +#endif + retvar->vval.v_number = get_vartv_string(&argvars[0])[0]; } /* @@ -3678,24 +4304,24 @@ f_char2nr(argvars, retvar) */ static void f_cindent(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CINDENT pos_T pos; linenr_T lnum; pos = curwin->w_cursor; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { curwin->w_cursor.lnum = lnum; - retvar->var_val.var_number = get_c_indent(); + retvar->vval.v_number = get_c_indent(); curwin->w_cursor = pos; } else #endif - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; } /* @@ -3703,8 +4329,8 @@ f_cindent(argvars, retvar) */ static void f_col(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { colnr_T col = 0; pos_T *fp; @@ -3747,7 +4373,7 @@ f_col(argvars, retvar) #endif } } - retvar->var_val.var_number = col; + retvar->vval.v_number = col; } /* @@ -3756,8 +4382,8 @@ f_col(argvars, retvar) /*ARGSUSED*/ static void f_confirm(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) char_u *message; @@ -3768,17 +4394,17 @@ f_confirm(argvars, retvar) int type = VIM_GENERIC; int c; - message = get_var_string(&argvars[0]); - if (argvars[1].var_type != VAR_UNKNOWN) - { - buttons = get_var_string_buf(&argvars[1], buf); - if (argvars[2].var_type != VAR_UNKNOWN) - { - def = get_var_number(&argvars[2]); - if (argvars[3].var_type != VAR_UNKNOWN) + message = get_vartv_string(&argvars[0]); + if (argvars[1].v_type != VAR_UNKNOWN) + { + buttons = get_vartv_string_buf(&argvars[1], buf); + if (argvars[2].v_type != VAR_UNKNOWN) + { + def = get_vartv_number(&argvars[2]); + if (argvars[3].v_type != VAR_UNKNOWN) { /* avoid that TOUPPER_ASC calls get_var_string_buf() twice */ - c = *get_var_string_buf(&argvars[3], buf2); + c = *get_vartv_string_buf(&argvars[3], buf2); switch (TOUPPER_ASC(c)) { case 'E': type = VIM_ERROR; break; @@ -3794,13 +4420,29 @@ f_confirm(argvars, retvar) if (buttons == NULL || *buttons == NUL) buttons = (char_u *)_("&Ok"); - retvar->var_val.var_number = do_dialog(type, NULL, message, buttons, + retvar->vval.v_number = do_dialog(type, NULL, message, buttons, def, NULL); #else - retvar->var_val.var_number = 0; -#endif -} - + retvar->vval.v_number = 0; +#endif +} + +/* + * "copy()" function + */ + static void +f_copy(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + if (argvars[0].v_type == VAR_LIST) + { + retvar->v_type = VAR_LIST; + retvar->vval.v_list = list_copy(argvars[0].vval.v_list, FALSE); + } + else + copy_vartv(&argvars[0], retvar); +} /* * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function @@ -3810,8 +4452,8 @@ f_confirm(argvars, retvar) /*ARGSUSED*/ static void f_cscope_connection(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CSCOPE int num = 0; @@ -3819,18 +4461,18 @@ f_cscope_connection(argvars, retvar) char_u *prepend = NULL; char_u buf[NUMBUFLEN]; - if (argvars[0].var_type != VAR_UNKNOWN - && argvars[1].var_type != VAR_UNKNOWN) - { - num = (int)get_var_number(&argvars[0]); - dbpath = get_var_string(&argvars[1]); - if (argvars[2].var_type != VAR_UNKNOWN) - prepend = get_var_string_buf(&argvars[2], buf); - } - - retvar->var_val.var_number = cs_connection(num, dbpath, prepend); + if (argvars[0].v_type != VAR_UNKNOWN + && argvars[1].v_type != VAR_UNKNOWN) + { + num = (int)get_vartv_number(&argvars[0]); + dbpath = get_vartv_string(&argvars[1]); + if (argvars[2].v_type != VAR_UNKNOWN) + prepend = get_vartv_string_buf(&argvars[2], buf); + } + + retvar->vval.v_number = cs_connection(num, dbpath, prepend); #else - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; #endif } @@ -3842,15 +4484,15 @@ f_cscope_connection(argvars, retvar) /*ARGSUSED*/ static void f_cursor(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { long line, col; - line = get_var_lnum(argvars); + line = get_vartv_lnum(argvars); if (line > 0) curwin->w_cursor.lnum = line; - col = get_var_number(&argvars[1]); + col = get_vartv_number(&argvars[1]); if (col > 0) curwin->w_cursor.col = col - 1; #ifdef FEAT_VIRTUALEDIT @@ -3869,70 +4511,20 @@ f_cursor(argvars, retvar) } /* - * "libcall()" function - */ - static void -f_libcall(argvars, retvar) - VAR argvars; - VAR retvar; -{ - libcall_common(argvars, retvar, VAR_STRING); -} - -/* - * "libcallnr()" function - */ - static void -f_libcallnr(argvars, retvar) - VAR argvars; - VAR retvar; -{ - libcall_common(argvars, retvar, VAR_NUMBER); -} - - static void -libcall_common(argvars, retvar, type) - VAR argvars; - VAR retvar; - int type; -{ -#ifdef FEAT_LIBCALL - char_u *string_in; - char_u **string_result; - int nr_result; -#endif - - retvar->var_type = type; - if (type == VAR_NUMBER) - retvar->var_val.var_number = 0; - else - retvar->var_val.var_string = NULL; - - if (check_restricted() || check_secure()) - return; - -#ifdef FEAT_LIBCALL - /* The first two args must be strings, otherwise its meaningless */ - if (argvars[0].var_type == VAR_STRING && argvars[1].var_type == VAR_STRING) - { - if (argvars[2].var_type == VAR_NUMBER) - string_in = NULL; - else - string_in = argvars[2].var_val.var_string; - if (type == VAR_NUMBER) - string_result = NULL; - else - string_result = &retvar->var_val.var_string; - if (mch_libcall(argvars[0].var_val.var_string, - argvars[1].var_val.var_string, - string_in, - argvars[2].var_val.var_number, - string_result, - &nr_result) == OK - && type == VAR_NUMBER) - retvar->var_val.var_number = nr_result; - } -#endif + * "deepcopy()" function + */ + static void +f_deepcopy(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + if (argvars[0].v_type == VAR_LIST) + { + retvar->v_type = VAR_LIST; + retvar->vval.v_list = list_copy(argvars[0].vval.v_list, TRUE); + } + else + copy_vartv(&argvars[0], retvar); } /* @@ -3940,13 +4532,13 @@ libcall_common(argvars, retvar, type) */ static void f_delete(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { if (check_restricted() || check_secure()) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0])); + retvar->vval.v_number = -1; + else + retvar->vval.v_number = mch_remove(get_vartv_string(&argvars[0])); } /* @@ -3955,13 +4547,13 @@ f_delete(argvars, retvar) /*ARGSUSED*/ static void f_did_filetype(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_AUTOCMD - retvar->var_val.var_number = did_filetype; + retvar->vval.v_number = did_filetype; #else - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; #endif } @@ -3971,11 +4563,11 @@ f_did_filetype(argvars, retvar) /*ARGSUSED*/ static void f_diff_filler(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_DIFF - retvar->var_val.var_number = diff_check_fill(curwin, get_var_lnum(argvars)); + retvar->vval.v_number = diff_check_fill(curwin, get_vartv_lnum(argvars)); #endif } @@ -3985,11 +4577,11 @@ f_diff_filler(argvars, retvar) /*ARGSUSED*/ static void f_diff_hlID(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_DIFF - linenr_T lnum = get_var_lnum(argvars); + linenr_T lnum = get_vartv_lnum(argvars); static linenr_T prev_lnum = 0; static int changedtick = 0; static int fnum = 0; @@ -4028,13 +4620,13 @@ f_diff_hlID(argvars, retvar) if (hlID == HLF_CHD || hlID == HLF_TXD) { - col = get_var_number(&argvars[1]) - 1; + col = get_vartv_number(&argvars[1]) - 1; if (col >= change_start && col <= change_end) hlID = HLF_TXD; /* changed text */ else hlID = HLF_CHD; /* changed line */ } - retvar->var_val.var_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; + retvar->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; #endif } @@ -4043,15 +4635,15 @@ f_diff_hlID(argvars, retvar) */ static void f_escape(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[NUMBUFLEN]; - retvar->var_val.var_string = - vim_strsave_escaped(get_var_string(&argvars[0]), - get_var_string_buf(&argvars[1], buf)); - retvar->var_type = VAR_STRING; + retvar->vval.v_string = + vim_strsave_escaped(get_vartv_string(&argvars[0]), + get_vartv_string_buf(&argvars[1], buf)); + retvar->v_type = VAR_STRING; } /* @@ -4060,10 +4652,10 @@ f_escape(argvars, retvar) /*ARGSUSED*/ static void f_eventhandler(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = vgetc_busy; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = vgetc_busy; } /* @@ -4071,10 +4663,10 @@ f_eventhandler(argvars, retvar) */ static void f_executable(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = mch_can_exe(get_var_string(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = mch_can_exe(get_vartv_string(&argvars[0])); } /* @@ -4082,15 +4674,15 @@ f_executable(argvars, retvar) */ static void f_exists(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; char_u *name; int n = FALSE; int len = 0; - p = get_var_string(&argvars[0]); + p = get_vartv_string(&argvars[0]); if (*p == '$') /* environment variable */ { /* first try "normal" environment variables (fast) */ @@ -4106,19 +4698,10 @@ f_exists(argvars, retvar) } } else if (*p == '&' || *p == '+') /* option */ - n = (get_option_var(&p, NULL, TRUE) == OK); + n = (get_option_vartv(&p, NULL, TRUE) == OK); else if (*p == '*') /* internal or user defined function */ { - ++p; - p = trans_function_name(&p, FALSE, TRUE); - if (p != NULL) - { - if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL) - n = (find_func(p) != NULL); - else if (ASCII_ISLOWER(*p)) - n = (find_internal_func(p) >= 0); - vim_free(p); - } + n = function_exists(p + 1); } else if (*p == ':') { @@ -4161,14 +4744,14 @@ f_exists(argvars, retvar) if (len == 0) len = get_id_len(&p); if (len != 0) - n = (get_var_var(name, len, NULL) == OK); + n = (get_var_vartv(name, len, NULL) == OK); #ifdef FEAT_MAGIC_BRACES vim_free(temp_string); #endif } - retvar->var_val.var_number = n; + retvar->vval.v_number = n; } /* @@ -4176,8 +4759,8 @@ f_exists(argvars, retvar) */ static void f_expand(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *s; int len; @@ -4185,23 +4768,23 @@ f_expand(argvars, retvar) int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; expand_T xpc; - retvar->var_type = VAR_STRING; - s = get_var_string(&argvars[0]); + retvar->v_type = VAR_STRING; + s = get_vartv_string(&argvars[0]); if (*s == '%' || *s == '#' || *s == '<') { ++emsg_off; - retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s); + retvar->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); --emsg_off; } else { /* When the optional second argument is non-zero, don't remove matches * for 'suffixes' and 'wildignore' */ - if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1])) + if (argvars[1].v_type != VAR_UNKNOWN && get_vartv_number(&argvars[1])) flags |= WILD_KEEP_ALL; ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; - retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); + retvar->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); ExpandCleanup(&xpc); } } @@ -4211,14 +4794,14 @@ f_expand(argvars, retvar) */ static void f_filereadable(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { FILE *fd; char_u *p; int n; - p = get_var_string(&argvars[0]); + p = get_vartv_string(&argvars[0]); if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) { n = TRUE; @@ -4227,7 +4810,7 @@ f_filereadable(argvars, retvar) else n = FALSE; - retvar->var_val.var_number = n; + retvar->vval.v_number = n; } /* @@ -4236,8 +4819,8 @@ f_filereadable(argvars, retvar) */ static void f_filewritable(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; int retval = 0; @@ -4245,7 +4828,7 @@ f_filewritable(argvars, retvar) int perm = 0; #endif - p = get_var_string(&argvars[0]); + p = get_vartv_string(&argvars[0]); #if defined(UNIX) || defined(VMS) perm = mch_getperm(p); #endif @@ -4266,7 +4849,7 @@ f_filewritable(argvars, retvar) if (mch_isdir(p)) ++retval; } - retvar->var_val.var_number = retval; + retvar->vval.v_number = retval; } /* @@ -4274,8 +4857,8 @@ f_filewritable(argvars, retvar) */ static void f_finddir(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { f_findfilendir(argvars, retvar, TRUE); } @@ -4285,16 +4868,16 @@ f_finddir(argvars, retvar) */ static void f_findfile(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { f_findfilendir(argvars, retvar, FALSE); } static void f_findfilendir(argvars, retvar, dir) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; int dir; { #ifdef FEAT_SEARCHPATH @@ -4306,16 +4889,16 @@ f_findfilendir(argvars, retvar, dir) int count = 1; int first = TRUE; - fname = get_var_string(&argvars[0]); - - if (argvars[1].var_type != VAR_UNKNOWN) - { - p = get_var_string_buf(&argvars[1], pathbuf); + fname = get_vartv_string(&argvars[0]); + + if (argvars[1].v_type != VAR_UNKNOWN) + { + p = get_vartv_string_buf(&argvars[1], pathbuf); if (*p != NUL) path = p; - if (argvars[2].var_type != VAR_UNKNOWN) - count = get_var_number(&argvars[2]); + if (argvars[2].v_type != VAR_UNKNOWN) + count = get_vartv_number(&argvars[2]); } do @@ -4327,11 +4910,11 @@ f_findfilendir(argvars, retvar, dir) first = FALSE; } while (--count > 0 && fresult != NULL); - retvar->var_val.var_string = fresult; + retvar->vval.v_string = fresult; #else - retvar->var_val.var_string = NULL; -#endif - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; +#endif + retvar->v_type = VAR_STRING; } /* @@ -4339,8 +4922,8 @@ f_findfilendir(argvars, retvar, dir) */ static void f_fnamemodify(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *fname; char_u *mods; @@ -4349,17 +4932,17 @@ f_fnamemodify(argvars, retvar) char_u *fbuf = NULL; char_u buf[NUMBUFLEN]; - fname = get_var_string(&argvars[0]); - mods = get_var_string_buf(&argvars[1], buf); + fname = get_vartv_string(&argvars[0]); + mods = get_vartv_string_buf(&argvars[1], buf); len = (int)STRLEN(fname); (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); - retvar->var_type = VAR_STRING; + retvar->v_type = VAR_STRING; if (fname == NULL) - retvar->var_val.var_string = NULL; - else - retvar->var_val.var_string = vim_strnsave(fname, len); + retvar->vval.v_string = NULL; + else + retvar->vval.v_string = vim_strnsave(fname, len); vim_free(fbuf); } @@ -4368,8 +4951,8 @@ f_fnamemodify(argvars, retvar) */ static void f_foldclosed(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { foldclosed_both(argvars, retvar, FALSE); } @@ -4379,8 +4962,8 @@ f_foldclosed(argvars, retvar) */ static void f_foldclosedend(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { foldclosed_both(argvars, retvar, TRUE); } @@ -4390,28 +4973,28 @@ f_foldclosedend(argvars, retvar) */ static void foldclosed_both(argvars, retvar, end) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; int end; { #ifdef FEAT_FOLDING linenr_T lnum; linenr_T first, last; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) { if (end) - retvar->var_val.var_number = (varnumber_T)last; + retvar->vval.v_number = (varnumber_T)last; else - retvar->var_val.var_number = (varnumber_T)first; + retvar->vval.v_number = (varnumber_T)first; return; } } #endif - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; } /* @@ -4419,18 +5002,18 @@ foldclosed_both(argvars, retvar, end) */ static void f_foldlevel(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_FOLDING linenr_T lnum; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) - retvar->var_val.var_number = foldLevel(lnum); - else -#endif - retvar->var_val.var_number = 0; + retvar->vval.v_number = foldLevel(lnum); + else +#endif + retvar->vval.v_number = 0; } /* @@ -4439,8 +5022,8 @@ f_foldlevel(argvars, retvar) /*ARGSUSED*/ static void f_foldtext(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_FOLDING linenr_T lnum; @@ -4450,8 +5033,8 @@ f_foldtext(argvars, retvar) char *txt; #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_FOLDING if ((linenr_T)vimvars[VV_FOLDSTART].val > 0 && (linenr_T)vimvars[VV_FOLDEND].val <= curbuf->b_ml.ml_line_count @@ -4494,7 +5077,7 @@ f_foldtext(argvars, retvar) STRCAT(r, s); /* remove 'foldmarker' and 'commentstring' */ foldtext_cleanup(r + len); - retvar->var_val.var_string = r; + retvar->vval.v_string = r; } } #endif @@ -4506,8 +5089,8 @@ f_foldtext(argvars, retvar) /*ARGSUSED*/ static void f_foldtextresult(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_FOLDING linenr_T lnum; @@ -4517,10 +5100,10 @@ f_foldtextresult(argvars, retvar) int fold_count; #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_FOLDING - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); fold_count = foldedCount(curwin, lnum, &foldinfo); if (fold_count > 0) { @@ -4528,7 +5111,7 @@ f_foldtextresult(argvars, retvar) &foldinfo, buf); if (text == buf) text = vim_strsave(text); - retvar->var_val.var_string = text; + retvar->vval.v_string = text; } #endif } @@ -4539,10 +5122,10 @@ f_foldtextresult(argvars, retvar) /*ARGSUSED*/ static void f_foreground(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = 0; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = 0; #ifdef FEAT_GUI if (gui.in_use) gui_mch_set_foreground(); @@ -4554,21 +5137,44 @@ f_foreground(argvars, retvar) } /* + * "function()" function + */ +/*ARGSUSED*/ + static void +f_function(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + char_u *s; + + s = get_vartv_string(&argvars[0]); + if (s == NULL || *s == NUL || isdigit(*s)) + EMSG2(_(e_invarg2), s); + else if (!function_exists(s)) + EMSG2(_("E999: Unknown function: %s"), s); + else + { + retvar->vval.v_string = vim_strsave(s); + retvar->v_type = VAR_FUNC; + } +} + +/* * "getchar()" function */ static void f_getchar(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { varnumber_T n; ++no_mapping; ++allow_keys; - if (argvars[0].var_type == VAR_UNKNOWN) + if (argvars[0].v_type == VAR_UNKNOWN) /* getchar(): blocking wait. */ n = safe_vgetc(); - else if (get_var_number(&argvars[0]) == 1) + else if (get_vartv_number(&argvars[0]) == 1) /* getchar(1): only check if char avail */ n = vpeekc(); else if (vpeekc() == NUL) @@ -4580,7 +5186,7 @@ f_getchar(argvars, retvar) --no_mapping; --allow_keys; - retvar->var_val.var_number = n; + retvar->vval.v_number = n; if (IS_SPECIAL(n) || mod_mask != 0) { char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ @@ -4606,8 +5212,8 @@ f_getchar(argvars, retvar) else temp[i++] = n; temp[i++] = NUL; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strsave(temp); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(temp); } } @@ -4617,10 +5223,10 @@ f_getchar(argvars, retvar) /*ARGSUSED*/ static void f_getcharmod(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = mod_mask; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = mod_mask; } /* @@ -4629,11 +5235,11 @@ f_getcharmod(argvars, retvar) /*ARGSUSED*/ static void f_getcmdline(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = get_cmdline_str(); + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = get_cmdline_str(); } /* @@ -4642,10 +5248,10 @@ f_getcmdline(argvars, retvar) /*ARGSUSED*/ static void f_getcmdpos(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = get_cmdline_pos() + 1; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = get_cmdline_pos() + 1; } /* @@ -4653,8 +5259,8 @@ f_getcmdpos(argvars, retvar) */ static void f_getbufvar(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; buf_T *save_curbuf; @@ -4662,11 +5268,11 @@ f_getbufvar(argvars, retvar) VAR v; ++emsg_off; - buf = get_buf_var(&argvars[0]); - varname = get_var_string(&argvars[1]); - - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + buf = get_buf_vartv(&argvars[0]); + varname = get_vartv_string(&argvars[1]); + + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; if (buf != NULL && varname != NULL) { @@ -4676,7 +5282,7 @@ f_getbufvar(argvars, retvar) save_curbuf = curbuf; curbuf = buf; - get_option_var(&varname, retvar, TRUE); + get_option_vartv(&varname, retvar, TRUE); /* restore previous notion of curbuf */ curbuf = save_curbuf; @@ -4686,7 +5292,7 @@ f_getbufvar(argvars, retvar) /* look up the variable */ v = find_var_in_ga(&buf->b_vars, varname); if (v != NULL) - copy_var(v, retvar); + copy_vartv(&v->tv, retvar); } } @@ -4699,19 +5305,19 @@ f_getbufvar(argvars, retvar) /*ARGSUSED*/ static void f_getcwd(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u cwd[MAXPATHL]; - retvar->var_type = VAR_STRING; + retvar->v_type = VAR_STRING; if (mch_dirname(cwd, MAXPATHL) == FAIL) - retvar->var_val.var_string = NULL; - else - { - retvar->var_val.var_string = vim_strsave(cwd); + retvar->vval.v_string = NULL; + else + { + retvar->vval.v_string = vim_strsave(cwd); #ifdef BACKSLASH_IN_FILENAME - slash_adjust(retvar->var_val.var_string); + slash_adjust(retvar->vval.v_string); #endif } } @@ -4722,18 +5328,18 @@ f_getcwd(argvars, retvar) /*ARGSUSED*/ static void f_getfontname(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_GUI if (gui.in_use) { GuiFont font; char_u *name = NULL; - if (argvars[0].var_type == VAR_UNKNOWN) + if (argvars[0].v_type == VAR_UNKNOWN) { /* Get the "Normal" font. Either the name saved by * hl_set_font_name() or from the font ID. */ @@ -4742,15 +5348,15 @@ f_getfontname(argvars, retvar) } else { - name = get_var_string(&argvars[0]); + name = get_vartv_string(&argvars[0]); if (STRCMP(name, "*") == 0) /* don't use font dialog */ return; font = gui_mch_get_font(name, FALSE); if (font == NOFONT) return; /* Invalid font name, return empty string. */ } - retvar->var_val.var_string = gui_mch_get_fontname(font, name); - if (argvars[0].var_type != VAR_UNKNOWN) + retvar->vval.v_string = gui_mch_get_fontname(font, name); + if (argvars[0].v_type != VAR_UNKNOWN) gui_mch_free_font(font); } #endif @@ -4761,8 +5367,8 @@ f_getfontname(argvars, retvar) */ static void f_getfperm(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *fname; struct stat st; @@ -4770,9 +5376,9 @@ f_getfperm(argvars, retvar) char_u flags[] = "rwx"; int i; - fname = get_var_string(&argvars[0]); - - retvar->var_type = VAR_STRING; + fname = get_vartv_string(&argvars[0]); + + retvar->v_type = VAR_STRING; if (mch_stat((char *)fname, &st) >= 0) { perm = vim_strsave((char_u *)"---------"); @@ -4785,7 +5391,7 @@ f_getfperm(argvars, retvar) } } } - retvar->var_val.var_string = perm; + retvar->vval.v_string = perm; } /* @@ -4793,25 +5399,25 @@ f_getfperm(argvars, retvar) */ static void f_getfsize(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *fname; struct stat st; - fname = get_var_string(&argvars[0]); - - retvar->var_type = VAR_NUMBER; + fname = get_vartv_string(&argvars[0]); + + retvar->v_type = VAR_NUMBER; if (mch_stat((char *)fname, &st) >= 0) { if (mch_isdir(fname)) - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; else - retvar->var_val.var_number = (varnumber_T)st.st_size; - } - else - retvar->var_val.var_number = -1; + retvar->vval.v_number = (varnumber_T)st.st_size; + } + else + retvar->vval.v_number = -1; } /* @@ -4819,18 +5425,18 @@ f_getfsize(argvars, retvar) */ static void f_getftime(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *fname; struct stat st; - fname = get_var_string(&argvars[0]); + fname = get_vartv_string(&argvars[0]); if (mch_stat((char *)fname, &st) >= 0) - retvar->var_val.var_number = (varnumber_T)st.st_mtime; - else - retvar->var_val.var_number = -1; + retvar->vval.v_number = (varnumber_T)st.st_mtime; + else + retvar->vval.v_number = -1; } /* @@ -4838,17 +5444,17 @@ f_getftime(argvars, retvar) */ static void f_getftype(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *fname; struct stat st; char_u *type = NULL; char *t; - fname = get_var_string(&argvars[0]); - - retvar->var_type = VAR_STRING; + fname = get_vartv_string(&argvars[0]); + + retvar->v_type = VAR_STRING; if (mch_lstat((char *)fname, &st) >= 0) { #ifdef S_ISREG @@ -4910,7 +5516,7 @@ f_getftype(argvars, retvar) #endif type = vim_strsave((char_u *)t); } - retvar->var_val.var_string = type; + retvar->vval.v_string = type; } /* @@ -4918,22 +5524,22 @@ f_getftype(argvars, retvar) */ static void f_getreg(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *strregname; int regname; - if (argvars[0].var_type != VAR_UNKNOWN) - strregname = get_var_string(&argvars[0]); + if (argvars[0].v_type != VAR_UNKNOWN) + strregname = get_vartv_string(&argvars[0]); else strregname = vimvars[VV_REG].val; regname = (strregname == NULL ? '"' : *strregname); if (regname == 0) regname = '"'; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = get_reg_contents(regname, TRUE); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = get_reg_contents(regname, TRUE); } /* @@ -4941,16 +5547,16 @@ f_getreg(argvars, retvar) */ static void f_getregtype(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *strregname; int regname; char_u buf[NUMBUFLEN + 2]; long reglen = 0; - if (argvars[0].var_type != VAR_UNKNOWN) - strregname = get_var_string(&argvars[0]); + if (argvars[0].v_type != VAR_UNKNOWN) + strregname = get_vartv_string(&argvars[0]); else /* Default to v:register */ strregname = vimvars[VV_REG].val; @@ -4972,8 +5578,8 @@ f_getregtype(argvars, retvar) break; #endif } - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strsave(buf); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(buf); } /* @@ -4981,21 +5587,21 @@ f_getregtype(argvars, retvar) */ static void f_getline(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum; char_u *p; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) p = ml_get(lnum); else p = (char_u *)""; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strsave(p); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(p); } /* @@ -5004,17 +5610,17 @@ f_getline(argvars, retvar) /*ARGSUSED*/ static void f_getwinposx(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = -1; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = -1; #ifdef FEAT_GUI if (gui.in_use) { int x, y; if (gui_mch_get_winpos(&x, &y) == OK) - retvar->var_val.var_number = x; + retvar->vval.v_number = x; } #endif } @@ -5025,17 +5631,17 @@ f_getwinposx(argvars, retvar) /*ARGSUSED*/ static void f_getwinposy(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = -1; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = -1; #ifdef FEAT_GUI if (gui.in_use) { int x, y; if (gui_mch_get_winpos(&x, &y) == OK) - retvar->var_val.var_number = y; + retvar->vval.v_number = y; } #endif } @@ -5045,8 +5651,8 @@ f_getwinposy(argvars, retvar) */ static void f_getwinvar(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { win_T *win, *oldcurwin; char_u *varname; @@ -5054,10 +5660,10 @@ f_getwinvar(argvars, retvar) ++emsg_off; win = find_win_by_nr(&argvars[0]); - varname = get_var_string(&argvars[1]); - - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + varname = get_vartv_string(&argvars[1]); + + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; if (win != NULL && varname != NULL) { @@ -5067,7 +5673,7 @@ f_getwinvar(argvars, retvar) oldcurwin = curwin; curwin = win; - get_option_var(&varname, retvar , 1); + get_option_vartv(&varname, retvar, 1); /* restore previous notion of curwin */ curwin = oldcurwin; @@ -5077,7 +5683,7 @@ f_getwinvar(argvars, retvar) /* look up the variable */ v = find_var_in_ga(&win->w_vars, varname); if (v != NULL) - copy_var(v, retvar); + copy_vartv(&v->tv, retvar); } } @@ -5089,15 +5695,15 @@ f_getwinvar(argvars, retvar) */ static void f_glob(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { expand_T xpc; ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]), + retvar->v_type = VAR_STRING; + retvar->vval.v_string = ExpandOne(&xpc, get_vartv_string(&argvars[0]), NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); ExpandCleanup(&xpc); } @@ -5107,14 +5713,14 @@ f_glob(argvars, retvar) */ static void f_globpath(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf1[NUMBUFLEN]; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = globpath(get_var_string(&argvars[0]), - get_var_string_buf(&argvars[1], buf1)); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = globpath(get_vartv_string(&argvars[0]), + get_vartv_string_buf(&argvars[1], buf1)); } /* @@ -5122,8 +5728,8 @@ f_globpath(argvars, retvar) */ static void f_has(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int i; char_u *name; @@ -5551,7 +6157,7 @@ f_has(argvars, retvar) NULL }; - name = get_var_string(&argvars[0]); + name = get_vartv_string(&argvars[0]); for (i = 0; has_list[i] != NULL; ++i) if (STRICMP(name, has_list[i]) == 0) { @@ -5611,7 +6217,7 @@ f_has(argvars, retvar) #endif } - retvar->var_val.var_number = n; + retvar->vval.v_number = n; } /* @@ -5619,23 +6225,23 @@ f_has(argvars, retvar) */ static void f_hasmapto(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *name; char_u *mode; char_u buf[NUMBUFLEN]; - name = get_var_string(&argvars[0]); - if (argvars[1].var_type == VAR_UNKNOWN) + name = get_vartv_string(&argvars[0]); + if (argvars[1].v_type == VAR_UNKNOWN) mode = (char_u *)"nvo"; else - mode = get_var_string_buf(&argvars[1], buf); + mode = get_vartv_string_buf(&argvars[1], buf); if (map_to_exists(name, mode)) - retvar->var_val.var_number = TRUE; - else - retvar->var_val.var_number = FALSE; + retvar->vval.v_number = TRUE; + else + retvar->vval.v_number = FALSE; } /* @@ -5644,8 +6250,8 @@ f_hasmapto(argvars, retvar) /*ARGSUSED*/ static void f_histadd(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CMDHIST int histype; @@ -5653,18 +6259,18 @@ f_histadd(argvars, retvar) char_u buf[NUMBUFLEN]; #endif - retvar->var_val.var_number = FALSE; + retvar->vval.v_number = FALSE; if (check_restricted() || check_secure()) return; #ifdef FEAT_CMDHIST - histype = get_histtype(get_var_string(&argvars[0])); + histype = get_histtype(get_vartv_string(&argvars[0])); if (histype >= 0) { - str = get_var_string_buf(&argvars[1], buf); + str = get_vartv_string_buf(&argvars[1], buf); if (*str != NUL) { add_to_history(histype, str, FALSE, NUL); - retvar->var_val.var_number = TRUE; + retvar->vval.v_number = TRUE; return; } } @@ -5677,27 +6283,27 @@ f_histadd(argvars, retvar) /*ARGSUSED*/ static void f_histdel(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CMDHIST int n; char_u buf[NUMBUFLEN]; - if (argvars[1].var_type == VAR_UNKNOWN) + if (argvars[1].v_type == VAR_UNKNOWN) /* only one argument: clear entire history */ - n = clr_history(get_histtype(get_var_string(&argvars[0]))); - else if (argvars[1].var_type == VAR_NUMBER) + n = clr_history(get_histtype(get_vartv_string(&argvars[0]))); + else if (argvars[1].v_type == VAR_NUMBER) /* index given: remove that entry */ - n = del_history_idx(get_histtype(get_var_string(&argvars[0])), - (int)get_var_number(&argvars[1])); + n = del_history_idx(get_histtype(get_vartv_string(&argvars[0])), + (int)get_vartv_number(&argvars[1])); else /* string given: remove all matching entries */ - n = del_history_entry(get_histtype(get_var_string(&argvars[0])), - get_var_string_buf(&argvars[1], buf)); - retvar->var_val.var_number = n; + n = del_history_entry(get_histtype(get_vartv_string(&argvars[0])), + get_vartv_string_buf(&argvars[1], buf)); + retvar->vval.v_number = n; #else - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; #endif } @@ -5707,23 +6313,23 @@ f_histdel(argvars, retvar) /*ARGSUSED*/ static void f_histget(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CMDHIST int type; int idx; - type = get_histtype(get_var_string(&argvars[0])); - if (argvars[1].var_type == VAR_UNKNOWN) + type = get_histtype(get_vartv_string(&argvars[0])); + if (argvars[1].v_type == VAR_UNKNOWN) idx = get_history_idx(type); else - idx = (int)get_var_number(&argvars[1]); - retvar->var_val.var_string = vim_strsave(get_history_entry(type, idx)); + idx = (int)get_vartv_number(&argvars[1]); + retvar->vval.v_string = vim_strsave(get_history_entry(type, idx)); #else - retvar->var_val.var_string = NULL; -#endif - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; +#endif + retvar->v_type = VAR_STRING; } /* @@ -5732,19 +6338,19 @@ f_histget(argvars, retvar) /*ARGSUSED*/ static void f_histnr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int i; #ifdef FEAT_CMDHIST - i = get_histtype(get_var_string(&argvars[0])); + i = get_histtype(get_vartv_string(&argvars[0])); if (i >= HIST_CMD && i < HIST_COUNT) i = get_history_idx(i); else #endif i = -1; - retvar->var_val.var_number = i; + retvar->vval.v_number = i; } /* @@ -5752,10 +6358,10 @@ f_histnr(argvars, retvar) */ static void f_hlexists(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = highlight_exists(get_vartv_string(&argvars[0])); } /* @@ -5763,10 +6369,10 @@ f_hlexists(argvars, retvar) */ static void f_hlID(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = syn_name2id(get_vartv_string(&argvars[0])); } /* @@ -5775,14 +6381,14 @@ f_hlID(argvars, retvar) /*ARGSUSED*/ static void f_hostname(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u hostname[256]; mch_get_host_name(hostname, 256); - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strsave(hostname); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(hostname); } /* @@ -5791,8 +6397,8 @@ f_hostname(argvars, retvar) /*ARGSUSED*/ static void f_iconv(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_MBYTE char_u buf1[NUMBUFLEN]; @@ -5801,21 +6407,21 @@ f_iconv(argvars, retvar) vimconv_T vimconv; #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_MBYTE - str = get_var_string(&argvars[0]); - from = enc_canonize(enc_skip(get_var_string_buf(&argvars[1], buf1))); - to = enc_canonize(enc_skip(get_var_string_buf(&argvars[2], buf2))); + str = get_vartv_string(&argvars[0]); + from = enc_canonize(enc_skip(get_vartv_string_buf(&argvars[1], buf1))); + to = enc_canonize(enc_skip(get_vartv_string_buf(&argvars[2], buf2))); vimconv.vc_type = CONV_NONE; convert_setup(&vimconv, from, to); /* If the encodings are equal, no conversion needed. */ if (vimconv.vc_type == CONV_NONE) - retvar->var_val.var_string = vim_strsave(str); - else - retvar->var_val.var_string = string_convert(&vimconv, str, NULL); + retvar->vval.v_string = vim_strsave(str); + else + retvar->vval.v_string = string_convert(&vimconv, str, NULL); convert_setup(&vimconv, NULL, NULL); vim_free(from); @@ -5828,16 +6434,16 @@ f_iconv(argvars, retvar) */ static void f_indent(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) - retvar->var_val.var_number = get_indent_lnum(lnum); - else - retvar->var_val.var_number = -1; + retvar->vval.v_number = get_indent_lnum(lnum); + else + retvar->vval.v_number = -1; } static int inputsecret_flag = 0; @@ -5848,22 +6454,22 @@ static int inputsecret_flag = 0; */ static void f_input(argvars, retvar) - VAR argvars; - VAR retvar; -{ - char_u *prompt = get_var_string(&argvars[0]); + typeval *argvars; + typeval *retvar; +{ + char_u *prompt = get_vartv_string(&argvars[0]); char_u *p = NULL; int c; char_u buf[NUMBUFLEN]; int cmd_silent_save = cmd_silent; - retvar->var_type = VAR_STRING; + retvar->v_type = VAR_STRING; #ifdef NO_CONSOLE_INPUT /* While starting up, there is no place to enter text. */ if (no_console_input()) { - retvar->var_val.var_string = NULL; + retvar->vval.v_string = NULL; return; } #endif @@ -5891,10 +6497,10 @@ f_input(argvars, retvar) cmdline_row = msg_row; } - if (argvars[1].var_type != VAR_UNKNOWN) - stuffReadbuffSpec(get_var_string_buf(&argvars[1], buf)); - - retvar->var_val.var_string = + if (argvars[1].v_type != VAR_UNKNOWN) + stuffReadbuffSpec(get_vartv_string_buf(&argvars[1], buf)); + + retvar->vval.v_string = getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); /* since the user typed this, no need to wait for return */ @@ -5908,8 +6514,8 @@ f_input(argvars, retvar) */ static void f_inputdialog(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #if defined(FEAT_GUI_TEXTDIALOG) /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ @@ -5918,27 +6524,27 @@ f_inputdialog(argvars, retvar) char_u *message; char_u buf[NUMBUFLEN]; - message = get_var_string(&argvars[0]); - if (argvars[1].var_type != VAR_UNKNOWN) - { - STRNCPY(IObuff, get_var_string_buf(&argvars[1], buf), IOSIZE); + message = get_vartv_string(&argvars[0]); + if (argvars[1].v_type != VAR_UNKNOWN) + { + STRNCPY(IObuff, get_vartv_string_buf(&argvars[1], buf), IOSIZE); IObuff[IOSIZE - 1] = NUL; } else IObuff[0] = NUL; if (do_dialog(VIM_QUESTION, NULL, message, (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) - retvar->var_val.var_string = vim_strsave(IObuff); + retvar->vval.v_string = vim_strsave(IObuff); else { - if (argvars[1].var_type != VAR_UNKNOWN - && argvars[2].var_type != VAR_UNKNOWN) - retvar->var_val.var_string = vim_strsave( - get_var_string_buf(&argvars[2], buf)); + if (argvars[1].v_type != VAR_UNKNOWN + && argvars[2].v_type != VAR_UNKNOWN) + retvar->vval.v_string = vim_strsave( + get_vartv_string_buf(&argvars[2], buf)); else - retvar->var_val.var_string = NULL; - } - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; + } + retvar->v_type = VAR_STRING; } else #endif @@ -5953,20 +6559,20 @@ static garray_T ga_userinput = {0, 0 /*ARGSUSED*/ static void f_inputrestore(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { if (ga_userinput.ga_len > 0) { --ga_userinput.ga_len; restore_typeahead((tasave_T *)(ga_userinput.ga_data) + ga_userinput.ga_len); - retvar->var_val.var_number = 0; /* OK */ + retvar->vval.v_number = 0; /* OK */ } else if (p_verbose > 1) { msg((char_u *)_("called inputrestore() more often than inputsave()")); - retvar->var_val.var_number = 1; /* Failed */ + retvar->vval.v_number = 1; /* Failed */ } } @@ -5976,8 +6582,8 @@ f_inputrestore(argvars, retvar) /*ARGSUSED*/ static void f_inputsave(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { /* Add an entry to the stack of typehead storage. */ if (ga_grow(&ga_userinput, 1) == OK) @@ -5985,10 +6591,10 @@ f_inputsave(argvars, retvar) save_typeahead((tasave_T *)(ga_userinput.ga_data) + ga_userinput.ga_len); ++ga_userinput.ga_len; - retvar->var_val.var_number = 0; /* OK */ - } - else - retvar->var_val.var_number = 1; /* Failed */ + retvar->vval.v_number = 0; /* OK */ + } + else + retvar->vval.v_number = 1; /* Failed */ } /* @@ -5996,8 +6602,8 @@ f_inputsave(argvars, retvar) */ static void f_inputsecret(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { ++cmdline_star; ++inputsecret_flag; @@ -6007,14 +6613,79 @@ f_inputsecret(argvars, retvar) } /* + * "insert()" function + */ + static void +f_insert(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + long before = 0; + long n; + listitem *item; + listitem *ni; + listvar *l; + + if (argvars[0].v_type != VAR_LIST) + EMSG(_("E999: First argument of insert() must be a list")); + else if ((l = argvars[0].vval.v_list) != NULL) + { + if (argvars[2].v_type != VAR_UNKNOWN) + before = get_vartv_number(&argvars[2]); + + if (before < 0) + { + /* Count from the end: -1 is before last item. */ + item = l->lv_last; + for (n = before + 1; n < 0 && item != NULL; ++n) + item = item->li_prev; + if (item == NULL) + n = 1; /* report an error, don't append */ + } + else + { + /* Can't use list_find() here, we allow one past the end. */ + item = l->lv_first; + for (n = before; n > 0 && item != NULL; --n) + item = item->li_next; + } + if (n > 0) + EMSGN(_(e_listidx), before); + else + { + ni = listitem_alloc(); + if (ni != NULL) + { + copy_vartv(&argvars[1], &ni->li_tv); + if (item == NULL) + /* Append new item at end of list. */ + list_append(l, ni); + else + { + /* Insert new item before existing item. */ + ni->li_prev = item->li_prev; + ni->li_next = item; + if (item->li_prev == NULL) + l->lv_first = ni; + else + item->li_prev->li_next = ni; + item->li_prev = ni; + } + copy_vartv(&argvars[0], retvar); + } + } + } +} + +/* * "isdirectory()" function */ static void f_isdirectory(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = mch_isdir(get_vartv_string(&argvars[0])); } /* @@ -6023,8 +6694,8 @@ f_isdirectory(argvars, retvar) /*ARGSUSED*/ static void f_last_buffer_nr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int n = 0; buf_T *buf; @@ -6033,7 +6704,98 @@ f_last_buffer_nr(argvars, retvar) if (n < buf->b_fnum) n = buf->b_fnum; - retvar->var_val.var_number = n; + retvar->vval.v_number = n; +} + +/* + * "len()" function + */ + static void +f_len(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + switch (argvars[0].v_type) + { + case VAR_STRING: + case VAR_NUMBER: + retvar->vval.v_number = (varnumber_T)STRLEN( + get_vartv_string(&argvars[0])); + break; + case VAR_LIST: + retvar->vval.v_number = list_len(argvars[0].vval.v_list); + break; + default: + EMSG(_("E999: Invalid type for len()")); + break; + } +} + +/* + * "libcall()" function + */ + static void +f_libcall(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + libcall_common(argvars, retvar, VAR_STRING); +} + +/* + * "libcallnr()" function + */ + static void +f_libcallnr(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + libcall_common(argvars, retvar, VAR_NUMBER); +} + + static void +libcall_common(argvars, retvar, type) + typeval *argvars; + typeval *retvar; + int type; +{ +#ifdef FEAT_LIBCALL + char_u *string_in; + char_u **string_result; + int nr_result; +#endif + + retvar->v_type = type; + if (type == VAR_NUMBER) + retvar->vval.v_number = 0; + else + retvar->vval.v_string = NULL; + + if (check_restricted() || check_secure()) + return; + +#ifdef FEAT_LIBCALL + /* The first two args must be strings, otherwise its meaningless */ + if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) + { + if (argvars[2].v_type == VAR_NUMBER) + string_in = NULL; + else + string_in = argvars[2].vval.v_string; + if (type == VAR_NUMBER) + string_result = NULL; + else + string_result = &retvar->vval.v_string; + if (mch_libcall(argvars[0].vval.v_string, + argvars[1].vval.v_string, + string_in, + argvars[2].vval.v_number, + string_result, + &nr_result) == OK + && type == VAR_NUMBER) + retvar->vval.v_number = nr_result; + } +#endif } /* @@ -6041,8 +6803,8 @@ f_last_buffer_nr(argvars, retvar) */ static void f_line(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum = 0; pos_T *fp; @@ -6050,7 +6812,7 @@ f_line(argvars, retvar) fp = var2fpos(&argvars[0], TRUE); if (fp != NULL) lnum = fp->lnum; - retvar->var_val.var_number = lnum; + retvar->vval.v_number = lnum; } /* @@ -6059,21 +6821,21 @@ f_line(argvars, retvar) /*ARGSUSED*/ static void f_line2byte(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifndef FEAT_BYTEOFF - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; #else linenr_T lnum; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = ml_find_line_or_offset(curbuf, lnum, NULL); - if (retvar->var_val.var_number >= 0) - ++retvar->var_val.var_number; + retvar->vval.v_number = -1; + else + retvar->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); + if (retvar->vval.v_number >= 0) + ++retvar->vval.v_number; #endif } @@ -6082,24 +6844,24 @@ f_line2byte(argvars, retvar) */ static void f_lispindent(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_LISP pos_T pos; linenr_T lnum; pos = curwin->w_cursor; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) { curwin->w_cursor.lnum = lnum; - retvar->var_val.var_number = get_lisp_indent(); + retvar->vval.v_number = get_lisp_indent(); curwin->w_cursor = pos; } else #endif - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; } /* @@ -6108,10 +6870,10 @@ f_lispindent(argvars, retvar) /*ARGSUSED*/ static void f_localtime(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = (varnumber_T)time(NULL); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = (varnumber_T)time(NULL); } /* @@ -6119,8 +6881,8 @@ f_localtime(argvars, retvar) */ static void f_maparg(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { get_maparg(argvars, retvar, TRUE); } @@ -6130,16 +6892,16 @@ f_maparg(argvars, retvar) */ static void f_mapcheck(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { get_maparg(argvars, retvar, FALSE); } static void get_maparg(argvars, retvar, exact) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; int exact; { char_u *keys; @@ -6151,15 +6913,15 @@ get_maparg(argvars, retvar, exact) garray_T ga; /* return empty string for failure */ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; - - keys = get_var_string(&argvars[0]); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; + + keys = get_vartv_string(&argvars[0]); if (*keys == NUL) return; - if (argvars[1].var_type != VAR_UNKNOWN) - which = get_var_string_buf(&argvars[1], buf); + if (argvars[1].v_type != VAR_UNKNOWN) + which = get_vartv_string_buf(&argvars[1], buf); else which = (char_u *)""; mode = get_map_mode(&which, 0); @@ -6177,7 +6939,7 @@ get_maparg(argvars, retvar, exact) ga_concat(&ga, str2special(&rhs, FALSE)); ga_append(&ga, NUL); - retvar->var_val.var_string = (char_u *)ga.ga_data; + retvar->vval.v_string = (char_u *)ga.ga_data; } } @@ -6186,8 +6948,8 @@ get_maparg(argvars, retvar, exact) */ static void f_match(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { find_some_match(argvars, retvar, 1); } @@ -6197,8 +6959,8 @@ f_match(argvars, retvar) */ static void f_matchend(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { find_some_match(argvars, retvar, 0); } @@ -6208,16 +6970,16 @@ f_matchend(argvars, retvar) */ static void f_matchstr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { find_some_match(argvars, retvar, 2); } static void find_some_match(argvars, retvar, type) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; int type; { char_u *str; @@ -6234,28 +6996,28 @@ find_some_match(argvars, retvar, type) save_cpo = p_cpo; p_cpo = (char_u *)""; - expr = str = get_var_string(&argvars[0]); - pat = get_var_string_buf(&argvars[1], patbuf); + expr = str = get_vartv_string(&argvars[0]); + pat = get_vartv_string_buf(&argvars[1], patbuf); if (type == 2) { - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; - } - else - retvar->var_val.var_number = -1; - - if (argvars[2].var_type != VAR_UNKNOWN) - { - start = get_var_number(&argvars[2]); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; + } + else + retvar->vval.v_number = -1; + + if (argvars[2].v_type != VAR_UNKNOWN) + { + start = get_vartv_number(&argvars[2]); if (start < 0) start = 0; if (start > (long)STRLEN(str)) goto theend; str += start; - if (argvars[3].var_type != VAR_UNKNOWN) - nth = get_var_number(&argvars[3]); + if (argvars[3].v_type != VAR_UNKNOWN) + nth = get_vartv_number(&argvars[3]); } regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); @@ -6279,17 +7041,17 @@ find_some_match(argvars, retvar, type) if (match) { if (type == 2) - retvar->var_val.var_string = vim_strnsave(regmatch.startp[0], + retvar->vval.v_string = vim_strnsave(regmatch.startp[0], (int)(regmatch.endp[0] - regmatch.startp[0])); else { if (type != 0) - retvar->var_val.var_number = + retvar->vval.v_number = (varnumber_T)(regmatch.startp[0] - str); else - retvar->var_val.var_number = + retvar->vval.v_number = (varnumber_T)(regmatch.endp[0] - str); - retvar->var_val.var_number += str - expr; + retvar->vval.v_number += str - expr; } } vim_free(regmatch.regprog); @@ -6305,8 +7067,8 @@ theend: /*ARGSUSED*/ static void f_mode(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[2]; @@ -6335,8 +7097,8 @@ f_mode(argvars, retvar) buf[0] = 'n'; buf[1] = NUL; - retvar->var_val.var_string = vim_strsave(buf); - retvar->var_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(buf); + retvar->v_type = VAR_STRING; } /* @@ -6344,22 +7106,50 @@ f_mode(argvars, retvar) */ static void f_nr2char(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[NUMBUFLEN]; #ifdef FEAT_MBYTE if (has_mbyte) - buf[(*mb_char2bytes)((int)get_var_number(&argvars[0]), buf)] = NUL; - else -#endif - { - buf[0] = (char_u)get_var_number(&argvars[0]); + buf[(*mb_char2bytes)((int)get_vartv_number(&argvars[0]), buf)] = NUL; + else +#endif + { + buf[0] = (char_u)get_vartv_number(&argvars[0]); buf[1] = NUL; } - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strsave(buf); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strsave(buf); +} + +/* + * "remove({list}, {idx})" function + */ + static void +f_remove(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + listvar *l; + listitem *item; + long idx; + + if (argvars[0].v_type != VAR_LIST) + EMSG(_("E999: First argument of remove() must be a list")); + else if ((l = argvars[0].vval.v_list) != NULL) + { + idx = get_vartv_number(&argvars[1]); + item = list_getrem(l, idx); + if (item == NULL) + EMSGN(_(e_listidx), idx); + else + { + *retvar = item->li_tv; + vim_free(item); + } + } } /* @@ -6367,16 +7157,16 @@ f_nr2char(argvars, retvar) */ static void f_rename(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[NUMBUFLEN]; if (check_restricted() || check_secure()) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = vim_rename(get_var_string(&argvars[0]), - get_var_string_buf(&argvars[1], buf)); + retvar->vval.v_number = -1; + else + retvar->vval.v_number = vim_rename(get_vartv_string(&argvars[0]), + get_vartv_string_buf(&argvars[1], buf)); } /* @@ -6384,21 +7174,21 @@ f_rename(argvars, retvar) */ static void f_resolve(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; - p = get_var_string(&argvars[0]); + p = get_vartv_string(&argvars[0]); #ifdef FEAT_SHORTCUT { char_u *v = NULL; v = mch_resolve_shortcut(p); if (v != NULL) - retvar->var_val.var_string = v; + retvar->vval.v_string = v; else - retvar->var_val.var_string = vim_strsave(p); + retvar->vval.v_string = vim_strsave(p); } #else # ifdef HAVE_READLINK @@ -6445,7 +7235,7 @@ f_resolve(argvars, retvar) vim_free(p); vim_free(remain); EMSG(_("E655: Too many symbolic links (cycle?)")); - retvar->var_val.var_string = NULL; + retvar->vval.v_string = NULL; goto fail; } @@ -6565,19 +7355,19 @@ f_resolve(argvars, retvar) *gettail_sep(p) = NUL; } - retvar->var_val.var_string = p; + retvar->vval.v_string = p; } # else - retvar->var_val.var_string = vim_strsave(p); + retvar->vval.v_string = vim_strsave(p); # endif #endif - simplify_filename(retvar->var_val.var_string); + simplify_filename(retvar->vval.v_string); #ifdef HAVE_READLINK fail: #endif - retvar->var_type = VAR_STRING; + retvar->v_type = VAR_STRING; } /* @@ -6585,15 +7375,15 @@ fail: */ static void f_simplify(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; - p = get_var_string(&argvars[0]); - retvar->var_val.var_string = vim_strsave(p); - simplify_filename(retvar->var_val.var_string); /* simplify in place */ - retvar->var_type = VAR_STRING; + p = get_vartv_string(&argvars[0]); + retvar->vval.v_string = vim_strsave(p); + simplify_filename(retvar->vval.v_string); /* simplify in place */ + retvar->v_type = VAR_STRING; } #define SP_NOMOVE 1 /* don't move cursor */ @@ -6605,8 +7395,8 @@ f_simplify(argvars, retvar) */ static void f_search(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *pat; pos_T pos; @@ -6615,15 +7405,15 @@ f_search(argvars, retvar) int dir; int flags = 0; - retvar->var_val.var_number = 0; /* default: FAIL */ - - pat = get_var_string(&argvars[0]); + retvar->vval.v_number = 0; /* default: FAIL */ + + pat = get_vartv_string(&argvars[0]); dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ if (dir == 0) goto theend; if ((flags & ~SP_NOMOVE) != 0) { - EMSG2(_(e_invarg2), get_var_string(&argvars[1])); + EMSG2(_(e_invarg2), get_vartv_string(&argvars[1])); goto theend; } @@ -6631,7 +7421,7 @@ f_search(argvars, retvar) if (searchit(curwin, curbuf, &pos, dir, pat, 1L, SEARCH_KEEP, RE_SEARCH) != FAIL) { - retvar->var_val.var_number = pos.lnum; + retvar->vval.v_number = pos.lnum; curwin->w_cursor = pos; /* "/$" will put the cursor after the end of the line, may need to * correct that here */ @@ -6650,8 +7440,8 @@ theend: */ static void f_searchpair(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *spat, *mpat, *epat; char_u *skip; @@ -6672,16 +7462,16 @@ f_searchpair(argvars, retvar) int nest = 1; int err; - retvar->var_val.var_number = 0; /* default: FAIL */ + retvar->vval.v_number = 0; /* default: FAIL */ /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ save_cpo = p_cpo; p_cpo = (char_u *)""; /* Get the three pattern arguments: start, middle, end. */ - spat = get_var_string(&argvars[0]); - mpat = get_var_string_buf(&argvars[1], nbuf1); - epat = get_var_string_buf(&argvars[2], nbuf2); + spat = get_vartv_string(&argvars[0]); + mpat = get_vartv_string_buf(&argvars[1], nbuf1); + epat = get_vartv_string_buf(&argvars[2], nbuf2); /* Make two search patterns: start/end (pat2, for in nested pairs) and * start/middle/end (pat3, for the top pair). */ @@ -6702,11 +7492,11 @@ f_searchpair(argvars, retvar) goto theend; /* Optional fifth argument: skip expresion */ - if (argvars[3].var_type == VAR_UNKNOWN - || argvars[4].var_type == VAR_UNKNOWN) + if (argvars[3].v_type == VAR_UNKNOWN + || argvars[4].v_type == VAR_UNKNOWN) skip = (char_u *)""; else - skip = get_var_string_buf(&argvars[4], nbuf3); + skip = get_vartv_string_buf(&argvars[4], nbuf3); save_cursor = curwin->w_cursor; pos = curwin->w_cursor; @@ -6734,7 +7524,7 @@ f_searchpair(argvars, retvar) { /* Evaluating {skip} caused an error, break here. */ curwin->w_cursor = save_cursor; - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; break; } if (r) @@ -6760,9 +7550,9 @@ f_searchpair(argvars, retvar) { /* Found the match: return matchcount or line number. */ if (flags & SP_RETCOUNT) - ++retvar->var_val.var_number; + ++retvar->vval.v_number; else - retvar->var_val.var_number = pos.lnum; + retvar->vval.v_number = pos.lnum; curwin->w_cursor = pos; if (!(flags & SP_REPEAT)) break; @@ -6771,7 +7561,7 @@ f_searchpair(argvars, retvar) } /* If 'n' flag is used or search failed: restore cursor position. */ - if ((flags & SP_NOMOVE) || retvar->var_val.var_number == 0) + if ((flags & SP_NOMOVE) || retvar->vval.v_number == 0) curwin->w_cursor = save_cursor; theend: @@ -6788,7 +7578,7 @@ theend: */ static int get_search_arg(varp, flagsp) - VAR varp; + typeval *varp; int *flagsp; { int dir = FORWARD; @@ -6796,9 +7586,9 @@ get_search_arg(varp, flagsp) char_u nbuf[NUMBUFLEN]; int mask; - if (varp->var_type != VAR_UNKNOWN) - { - flags = get_var_string_buf(varp, nbuf); + if (varp->v_type != VAR_UNKNOWN) + { + flags = get_vartv_string_buf(varp, nbuf); while (*flags != NUL) { switch (*flags) @@ -6836,8 +7626,8 @@ get_search_arg(varp, flagsp) /*ARGSUSED*/ static void f_setbufvar(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { buf_T *buf; #ifdef FEAT_AUTOCMD @@ -6846,14 +7636,14 @@ f_setbufvar(argvars, retvar) buf_T *save_curbuf; #endif char_u *varname, *bufvarname; - VAR varp; + typeval *varp; char_u nbuf[NUMBUFLEN]; if (check_restricted() || check_secure()) return; ++emsg_off; - buf = get_buf_var(&argvars[0]); - varname = get_var_string(&argvars[1]); + buf = get_buf_vartv(&argvars[0]); + varname = get_vartv_string(&argvars[1]); varp = &argvars[2]; if (buf != NULL && varname != NULL && varp != NULL) @@ -6869,8 +7659,8 @@ f_setbufvar(argvars, retvar) if (*varname == '&') { ++varname; - set_option_value(varname, get_var_number(varp), - get_var_string_buf(varp, nbuf), OPT_LOCAL); + set_option_value(varname, get_vartv_number(varp), + get_vartv_string_buf(varp, nbuf), OPT_LOCAL); } else { @@ -6899,11 +7689,11 @@ f_setbufvar(argvars, retvar) */ static void f_setcmdpos(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = set_cmdline_pos( - (int)get_var_number(&argvars[0]) - 1); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = set_cmdline_pos( + (int)get_vartv_number(&argvars[0]) - 1); } /* @@ -6911,15 +7701,15 @@ f_setcmdpos(argvars, retvar) */ static void f_setline(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum; char_u *line; - lnum = get_var_lnum(argvars); - line = get_var_string(&argvars[1]); - retvar->var_val.var_number = 1; /* FAIL is default */ + lnum = get_vartv_lnum(argvars); + line = get_vartv_string(&argvars[1]); + retvar->vval.v_number = 1; /* FAIL is default */ if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count @@ -6928,7 +7718,7 @@ f_setline(argvars, retvar) { changed_bytes(lnum, 0); check_cursor_col(); - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; } } @@ -6937,8 +7727,8 @@ f_setline(argvars, retvar) */ static void f_setreg(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int regname; char_u *strregname; @@ -6951,8 +7741,8 @@ f_setreg(argvars, retvar) yank_type = MAUTO; append = FALSE; - strregname = get_var_string(argvars); - retvar->var_val.var_number = 1; /* FAIL is default */ + strregname = get_vartv_string(argvars); + retvar->vval.v_number = 1; /* FAIL is default */ regname = (strregname == NULL ? '"' : *strregname); if (regname == 0 || regname == '@') @@ -6960,9 +7750,9 @@ f_setreg(argvars, retvar) else if (regname == '=') return; - if (argvars[2].var_type != VAR_UNKNOWN) - { - for (stropt = get_var_string(&argvars[2]); *stropt != NUL; ++stropt) + if (argvars[2].v_type != VAR_UNKNOWN) + { + for (stropt = get_vartv_string(&argvars[2]); *stropt != NUL; ++stropt) switch (*stropt) { case 'a': case 'A': /* append */ @@ -6988,9 +7778,9 @@ f_setreg(argvars, retvar) } } - write_reg_contents_ex(regname, get_var_string(&argvars[1]), -1, + write_reg_contents_ex(regname, get_vartv_string(&argvars[1]), -1, append, yank_type, block_len); - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; } @@ -7000,22 +7790,22 @@ f_setreg(argvars, retvar) /*ARGSUSED*/ static void f_setwinvar(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { win_T *win; #ifdef FEAT_WINDOWS win_T *save_curwin; #endif char_u *varname, *winvarname; - VAR varp; + typeval *varp; char_u nbuf[NUMBUFLEN]; if (check_restricted() || check_secure()) return; ++emsg_off; win = find_win_by_nr(&argvars[0]); - varname = get_var_string(&argvars[1]); + varname = get_vartv_string(&argvars[1]); varp = &argvars[2]; if (win != NULL && varname != NULL && varp != NULL) @@ -7030,8 +7820,8 @@ f_setwinvar(argvars, retvar) if (*varname == '&') { ++varname; - set_option_value(varname, get_var_number(varp), - get_var_string_buf(varp, nbuf), OPT_LOCAL); + set_option_value(varname, get_vartv_number(varp), + get_vartv_string_buf(varp, nbuf), OPT_LOCAL); } else { @@ -7063,12 +7853,12 @@ f_setwinvar(argvars, retvar) */ static void f_nextnonblank(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum; - for (lnum = get_var_lnum(argvars); ; ++lnum) + for (lnum = get_vartv_lnum(argvars); ; ++lnum) { if (lnum > curbuf->b_ml.ml_line_count) { @@ -7078,7 +7868,7 @@ f_nextnonblank(argvars, retvar) if (*skipwhite(ml_get(lnum)) != NUL) break; } - retvar->var_val.var_number = lnum; + retvar->vval.v_number = lnum; } /* @@ -7086,18 +7876,18 @@ f_nextnonblank(argvars, retvar) */ static void f_prevnonblank(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { linenr_T lnum; - lnum = get_var_lnum(argvars); + lnum = get_vartv_lnum(argvars); if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) lnum = 0; else while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) --lnum; - retvar->var_val.var_number = lnum; + retvar->vval.v_number = lnum; } #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) @@ -7135,8 +7925,8 @@ check_connection() /*ARGSUSED*/ static void f_serverlist(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *r = NULL; @@ -7149,15 +7939,15 @@ f_serverlist(argvars, retvar) r = serverGetVimNames(X_DISPLAY); # endif #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = r; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = r; } /*ARGSUSED*/ static void f_remote_peek(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CLIENTSERVER var v; @@ -7168,44 +7958,44 @@ f_remote_peek(argvars, retvar) if (check_restricted() || check_secure()) { - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; return; } # ifdef WIN32 - sscanf(get_var_string(&argvars[0]), "%x", &n); + sscanf(get_vartv_string(&argvars[0]), "%x", &n); if (n == 0) - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; else { s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); - retvar->var_val.var_number = (s != NULL); + retvar->vval.v_number = (s != NULL); } # else - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; if (check_connection() == FAIL) return; - retvar->var_val.var_number = serverPeekReply(X_DISPLAY, - serverStrToWin(get_var_string(&argvars[0])), &s); + retvar->vval.v_number = serverPeekReply(X_DISPLAY, + serverStrToWin(get_vartv_string(&argvars[0])), &s); # endif - if (argvars[1].var_type != VAR_UNKNOWN && retvar->var_val.var_number > 0) - { - v.var_type = VAR_STRING; - v.var_val.var_string = vim_strsave(s); - set_var(get_var_string(&argvars[1]), &v, FALSE); - vim_free(v.var_val.var_string); + if (argvars[1].v_type != VAR_UNKNOWN && retvar->vval.v_number > 0) + { + v.tv.v_type = VAR_STRING; + v.tv.vval.v_string = vim_strsave(s); + set_var(get_vartv_string(&argvars[1]), &v.tv, FALSE); + vim_free(v.tv.vval.v_string); } #else - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; #endif } /*ARGSUSED*/ static void f_remote_read(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *r = NULL; @@ -7216,33 +8006,33 @@ f_remote_read(argvars, retvar) /* The server's HWND is encoded in the 'id' parameter */ int n = 0; - sscanf(get_var_string(&argvars[0]), "%x", &n); + sscanf(get_vartv_string(&argvars[0]), "%x", &n); if (n != 0) r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); if (r == NULL) # else if (check_connection() == FAIL || serverReadReply(X_DISPLAY, - serverStrToWin(get_var_string(&argvars[0])), &r, FALSE) < 0) + serverStrToWin(get_vartv_string(&argvars[0])), &r, FALSE) < 0) # endif EMSG(_("E277: Unable to read a server reply")); } #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = r; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = r; } /*ARGSUSED*/ static void f_server2client(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_CLIENTSERVER char_u buf[NUMBUFLEN]; - char_u *server = get_var_string(&argvars[0]); - char_u *reply = get_var_string_buf(&argvars[1], buf); - - retvar->var_val.var_number = -1; + char_u *server = get_vartv_string(&argvars[0]); + char_u *reply = get_vartv_string_buf(&argvars[1], buf); + + retvar->vval.v_number = -1; if (check_restricted() || check_secure()) return; # ifdef FEAT_X11 @@ -7255,19 +8045,19 @@ f_server2client(argvars, retvar) EMSG(_("E258: Unable to send to client")); return; } - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; #else - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; #endif } #ifdef FEAT_CLIENTSERVER -static void remote_common __ARGS((VAR argvars, VAR retvar, int expr)); +static void remote_common __ARGS((typeval *argvars, typeval *retvar, int expr)); static void remote_common(argvars, retvar, expr) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; int expr; { char_u *server_name; @@ -7288,8 +8078,8 @@ remote_common(argvars, retvar, expr) return; # endif - server_name = get_var_string(&argvars[0]); - keys = get_var_string_buf(&argvars[1], buf); + server_name = get_vartv_string(&argvars[0]); + keys = get_vartv_string_buf(&argvars[1], buf); # ifdef WIN32 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) # else @@ -7304,18 +8094,18 @@ remote_common(argvars, retvar, expr) return; } - retvar->var_val.var_string = r; - - if (argvars[2].var_type != VAR_UNKNOWN) + retvar->vval.v_string = r; + + if (argvars[2].v_type != VAR_UNKNOWN) { var v; char_u str[30]; sprintf((char *)str, "0x%x", (unsigned int)w); - v.var_type = VAR_STRING; - v.var_val.var_string = vim_strsave(str); - set_var(get_var_string(&argvars[2]), &v, FALSE); - vim_free(v.var_val.var_string); + v.tv.v_type = VAR_STRING; + v.tv.vval.v_string = vim_strsave(str); + set_var(get_vartv_string(&argvars[2]), &v.tv, FALSE); + vim_free(v.tv.vval.v_string); } } #endif @@ -7326,11 +8116,11 @@ remote_common(argvars, retvar, expr) /*ARGSUSED*/ static void f_remote_expr(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_CLIENTSERVER remote_common(argvars, retvar, TRUE); #endif @@ -7342,11 +8132,11 @@ f_remote_expr(argvars, retvar) /*ARGSUSED*/ static void f_remote_send(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; #ifdef FEAT_CLIENTSERVER remote_common(argvars, retvar, FALSE); #endif @@ -7358,21 +8148,21 @@ f_remote_send(argvars, retvar) /*ARGSUSED*/ static void f_remote_foreground(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = 0; + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = 0; #ifdef FEAT_CLIENTSERVER # ifdef WIN32 /* On Win32 it's done in this application. */ - serverForeground(get_var_string(&argvars[0])); + serverForeground(get_vartv_string(&argvars[0])); # else /* Send a foreground() expression to the server. */ - argvars[1].var_type = VAR_STRING; - argvars[1].var_val.var_string = vim_strsave((char_u *)"foreground()"); - argvars[2].var_type = VAR_UNKNOWN; + argvars[1].v_type = VAR_STRING; + argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); + argvars[2].v_type = VAR_UNKNOWN; remote_common(argvars, retvar, TRUE); - vim_free(argvars[1].var_val.var_string); + vim_free(argvars[1].vval.v_string); # endif #endif } @@ -7383,8 +8173,8 @@ f_remote_foreground(argvars, retvar) /*ARGSUSED*/ static void f_repeat(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; int n; @@ -7393,11 +8183,11 @@ f_repeat(argvars, retvar) char_u *r; int i; - p = get_var_string(&argvars[0]); - n = get_var_number(&argvars[1]); - - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + p = get_vartv_string(&argvars[0]); + n = get_vartv_number(&argvars[1]); + + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; slen = (int)STRLEN(p); len = slen * n; @@ -7413,7 +8203,7 @@ f_repeat(argvars, retvar) r[len] = NUL; } - retvar->var_val.var_string = r; + retvar->vval.v_string = r; } #ifdef HAVE_STRFTIME @@ -7422,25 +8212,25 @@ f_repeat(argvars, retvar) */ static void f_strftime(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u result_buf[256]; struct tm *curtime; time_t seconds; char_u *p; - retvar->var_type = VAR_STRING; - - p = get_var_string(&argvars[0]); - if (argvars[1].var_type == VAR_UNKNOWN) + retvar->v_type = VAR_STRING; + + p = get_vartv_string(&argvars[0]); + if (argvars[1].v_type == VAR_UNKNOWN) seconds = time(NULL); else - seconds = (time_t)get_var_number(&argvars[1]); + seconds = (time_t)get_vartv_number(&argvars[1]); curtime = localtime(&seconds); /* MSVC returns NULL for an invalid value of seconds. */ if (curtime == NULL) - retvar->var_val.var_string = vim_strsave((char_u *)_("(Invalid)")); + retvar->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); else { # ifdef FEAT_MBYTE @@ -7464,11 +8254,10 @@ f_strftime(argvars, retvar) vim_free(p); convert_setup(&conv, enc, p_enc); if (conv.vc_type != CONV_NONE) - retvar->var_val.var_string = - string_convert(&conv, result_buf, NULL); + retvar->vval.v_string = string_convert(&conv, result_buf, NULL); else # endif - retvar->var_val.var_string = vim_strsave(result_buf); + retvar->vval.v_string = vim_strsave(result_buf); # ifdef FEAT_MBYTE /* Release conversion descriptors */ @@ -7484,22 +8273,22 @@ f_strftime(argvars, retvar) */ static void f_stridx(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[NUMBUFLEN]; char_u *needle; char_u *haystack; char_u *pos; - needle = get_var_string(&argvars[1]); - haystack = get_var_string_buf(&argvars[0], buf); + needle = get_vartv_string(&argvars[1]); + haystack = get_vartv_string_buf(&argvars[0], buf); pos = (char_u *)strstr((char *)haystack, (char *)needle); if (pos == NULL) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = (varnumber_T) (pos - haystack); + retvar->vval.v_number = -1; + else + retvar->vval.v_number = (varnumber_T) (pos - haystack); } /* @@ -7507,8 +8296,8 @@ f_stridx(argvars, retvar) */ static void f_strridx(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u buf[NUMBUFLEN]; char_u *needle; @@ -7516,8 +8305,8 @@ f_strridx(argvars, retvar) char_u *rest; char_u *lastmatch = NULL; - needle = get_var_string(&argvars[1]); - haystack = get_var_string_buf(&argvars[0], buf); + needle = get_vartv_string(&argvars[1]); + haystack = get_vartv_string_buf(&argvars[0], buf); if (*needle == NUL) /* Empty string matches past the end. */ lastmatch = haystack + STRLEN(haystack); @@ -7531,9 +8320,25 @@ f_strridx(argvars, retvar) } if (lastmatch == NULL) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = (varnumber_T)(lastmatch - haystack); + retvar->vval.v_number = -1; + else + retvar->vval.v_number = (varnumber_T)(lastmatch - haystack); +} + +/* + * "string()" function + */ + static void +f_string(argvars, retvar) + typeval *argvars; + typeval *retvar; +{ + char_u *tofree; + + retvar->v_type = VAR_STRING; + retvar->vval.v_string = tv2string(&argvars[0], &tofree); + if (tofree == NULL) + retvar->vval.v_string = vim_strsave(retvar->vval.v_string); } /* @@ -7541,10 +8346,11 @@ f_strridx(argvars, retvar) */ static void f_strlen(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_val.var_number = (varnumber_T) (STRLEN(get_var_string(&argvars[0]))); + typeval *argvars; + typeval *retvar; +{ + retvar->vval.v_number = (varnumber_T)(STRLEN( + get_vartv_string(&argvars[0]))); } /* @@ -7552,20 +8358,20 @@ f_strlen(argvars, retvar) */ static void f_strpart(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; int n; int len; int slen; - p = get_var_string(&argvars[0]); + p = get_vartv_string(&argvars[0]); slen = (int)STRLEN(p); - n = get_var_number(&argvars[1]); - if (argvars[2].var_type != VAR_UNKNOWN) - len = get_var_number(&argvars[2]); + n = get_vartv_number(&argvars[1]); + if (argvars[2].v_type != VAR_UNKNOWN) + len = get_vartv_number(&argvars[2]); else len = slen - n; /* default len: all bytes that are available. */ @@ -7585,8 +8391,8 @@ f_strpart(argvars, retvar) else if (n + len > slen) len = slen - n; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_strnsave(p + n, len); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_strnsave(p + n, len); } /* @@ -7594,11 +8400,11 @@ f_strpart(argvars, retvar) */ static void f_strtrans(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = transstr(get_var_string(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = transstr(get_vartv_string(&argvars[0])); } /* @@ -7607,8 +8413,8 @@ f_strtrans(argvars, retvar) /*ARGSUSED*/ static void f_synID(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int id = 0; #ifdef FEAT_SYN_HL @@ -7616,16 +8422,16 @@ f_synID(argvars, retvar) long col; int trans; - line = get_var_lnum(argvars); - col = get_var_number(&argvars[1]) - 1; - trans = get_var_number(&argvars[2]); + line = get_vartv_lnum(argvars); + col = get_vartv_number(&argvars[1]) - 1; + trans = get_vartv_number(&argvars[2]); if (line >= 1 && line <= curbuf->b_ml.ml_line_count && col >= 0 && col < (long)STRLEN(ml_get(line))) id = syn_get_id(line, col, trans); #endif - retvar->var_val.var_number = id; + retvar->vval.v_number = id; } /* @@ -7634,8 +8440,8 @@ f_synID(argvars, retvar) /*ARGSUSED*/ static void f_synIDattr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p = NULL; #ifdef FEAT_SYN_HL @@ -7645,11 +8451,11 @@ f_synIDattr(argvars, retvar) char_u modebuf[NUMBUFLEN]; int modec; - id = get_var_number(&argvars[0]); - what = get_var_string(&argvars[1]); - if (argvars[2].var_type != VAR_UNKNOWN) - { - mode = get_var_string_buf(&argvars[2], modebuf); + id = get_vartv_number(&argvars[0]); + what = get_vartv_string(&argvars[1]); + if (argvars[2].v_type != VAR_UNKNOWN) + { + mode = get_vartv_string_buf(&argvars[2], modebuf); modec = TOLOWER_ASC(mode[0]); if (modec != 't' && modec != 'c' #ifdef FEAT_GUI @@ -7712,8 +8518,8 @@ f_synIDattr(argvars, retvar) if (p != NULL) p = vim_strsave(p); #endif - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = p; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = p; } /* @@ -7722,13 +8528,13 @@ f_synIDattr(argvars, retvar) /*ARGSUSED*/ static void f_synIDtrans(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int id; #ifdef FEAT_SYN_HL - id = get_var_number(&argvars[0]); + id = get_vartv_number(&argvars[0]); if (id > 0) id = syn_get_final_id(id); @@ -7736,7 +8542,7 @@ f_synIDtrans(argvars, retvar) #endif id = 0; - retvar->var_val.var_number = id; + retvar->vval.v_number = id; } /* @@ -7744,8 +8550,8 @@ f_synIDtrans(argvars, retvar) */ static void f_system(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *res = NULL; char_u *p; @@ -7754,7 +8560,7 @@ f_system(argvars, retvar) int err = FALSE; FILE *fd; - if (argvars[1].var_type != VAR_UNKNOWN) + if (argvars[1].v_type != VAR_UNKNOWN) { /* * Write the string to a temp file, to be used for input of the shell @@ -7772,7 +8578,7 @@ f_system(argvars, retvar) EMSG2(_(e_notopen), infile); goto done; } - p = get_var_string_buf(&argvars[1], buf); + p = get_vartv_string_buf(&argvars[1], buf); if (fwrite(p, STRLEN(p), 1, fd) != 1) err = TRUE; if (fclose(fd) != 0) @@ -7784,7 +8590,7 @@ f_system(argvars, retvar) } } - res = get_cmd_output(get_var_string(&argvars[0]), infile, SHELL_SILENT); + res = get_cmd_output(get_vartv_string(&argvars[0]), infile, SHELL_SILENT); #ifdef USE_CR /* translate into */ @@ -7823,8 +8629,8 @@ done: mch_remove(infile); vim_free(infile); } - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = res; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = res; } /* @@ -7832,11 +8638,11 @@ done: */ static void f_submatch(argvars, retvar) - VAR argvars; - VAR retvar; -{ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = reg_submatch((int)get_var_number(&argvars[0])); + typeval *argvars; + typeval *retvar; +{ + retvar->v_type = VAR_STRING; + retvar->vval.v_string = reg_submatch((int)get_vartv_number(&argvars[0])); } /* @@ -7844,19 +8650,19 @@ f_submatch(argvars, retvar) */ static void f_substitute(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u patbuf[NUMBUFLEN]; char_u subbuf[NUMBUFLEN]; char_u flagsbuf[NUMBUFLEN]; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = do_string_sub( - get_var_string(&argvars[0]), - get_var_string_buf(&argvars[1], patbuf), - get_var_string_buf(&argvars[2], subbuf), - get_var_string_buf(&argvars[3], flagsbuf)); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = do_string_sub( + get_vartv_string(&argvars[0]), + get_vartv_string_buf(&argvars[1], patbuf), + get_vartv_string_buf(&argvars[2], subbuf), + get_vartv_string_buf(&argvars[3], flagsbuf)); } /* @@ -7865,13 +8671,13 @@ f_substitute(argvars, retvar) /*ARGSUSED*/ static void f_tempname(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { static int x = 'A'; - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = vim_tempname(x); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = vim_tempname(x); /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different * names. Skip 'I' and 'O', they are used for shell redirection. */ @@ -7900,14 +8706,14 @@ f_tempname(argvars, retvar) */ static void f_tolower(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; - p = vim_strsave(get_var_string(&argvars[0])); - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = p; + p = vim_strsave(get_vartv_string(&argvars[0])); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = p; if (p != NULL) while (*p != NUL) @@ -7943,14 +8749,14 @@ f_tolower(argvars, retvar) */ static void f_toupper(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *p; - p = vim_strsave(get_var_string(&argvars[0])); - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = p; + p = vim_strsave(get_vartv_string(&argvars[0])); + retvar->v_type = VAR_STRING; + retvar->vval.v_string = p; if (p != NULL) while (*p != NUL) @@ -7986,8 +8792,8 @@ f_toupper(argvars, retvar) */ static void f_tr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { char_u *instr; char_u *fromstr; @@ -8006,13 +8812,13 @@ f_tr(argvars, retvar) char_u buf2[NUMBUFLEN]; garray_T ga; - instr = get_var_string(&argvars[0]); - fromstr = get_var_string_buf(&argvars[1], buf); - tostr = get_var_string_buf(&argvars[2], buf2); + instr = get_vartv_string(&argvars[0]); + fromstr = get_vartv_string_buf(&argvars[1], buf); + tostr = get_vartv_string_buf(&argvars[2], buf2); /* Default return value: empty string. */ - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = NULL; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = NULL; ga_init2(&ga, (int)sizeof(char), 80); #ifdef FEAT_MBYTE @@ -8095,7 +8901,7 @@ error: } } - retvar->var_val.var_string = ga.ga_data; + retvar->vval.v_string = ga.ga_data; } /* @@ -8103,13 +8909,13 @@ error: */ static void f_type(argvars, retvar) - VAR argvars; - VAR retvar; -{ - if (argvars[0].var_type == VAR_NUMBER) - retvar->var_val.var_number = 0; - else - retvar->var_val.var_number = 1; + typeval *argvars; + typeval *retvar; +{ + if (argvars[0].v_type == VAR_NUMBER) + retvar->vval.v_number = 0; + else + retvar->vval.v_number = 1; } /* @@ -8117,8 +8923,8 @@ f_type(argvars, retvar) */ static void f_virtcol(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { colnr_T vcol = 0; pos_T *fp; @@ -8130,7 +8936,7 @@ f_virtcol(argvars, retvar) ++vcol; } - retvar->var_val.var_number = vcol; + retvar->vval.v_number = vcol; } /* @@ -8139,25 +8945,25 @@ f_virtcol(argvars, retvar) /*ARGSUSED*/ static void f_visualmode(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_VISUAL char_u str[2]; - retvar->var_type = VAR_STRING; + retvar->v_type = VAR_STRING; str[0] = curbuf->b_visual_mode_eval; str[1] = NUL; - retvar->var_val.var_string = vim_strsave(str); + retvar->vval.v_string = vim_strsave(str); /* A non-zero number or non-empty string argument: reset mode. */ - if ((argvars[0].var_type == VAR_NUMBER - && argvars[0].var_val.var_number != 0) - || (argvars[0].var_type == VAR_STRING - && *get_var_string(&argvars[0]) != NUL)) + if ((argvars[0].v_type == VAR_NUMBER + && argvars[0].vval.v_number != 0) + || (argvars[0].v_type == VAR_STRING + && *get_vartv_string(&argvars[0]) != NUL)) curbuf->b_visual_mode_eval = NUL; #else - retvar->var_val.var_number = 0; /* return anything, it won't work anyway */ + retvar->vval.v_number = 0; /* return anything, it won't work anyway */ #endif } @@ -8166,16 +8972,16 @@ f_visualmode(argvars, retvar) */ static void f_winbufnr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { win_T *wp; wp = find_win_by_nr(&argvars[0]); if (wp == NULL) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = wp->w_buffer->b_fnum; + retvar->vval.v_number = -1; + else + retvar->vval.v_number = wp->w_buffer->b_fnum; } /* @@ -8184,11 +8990,11 @@ f_winbufnr(argvars, retvar) /*ARGSUSED*/ static void f_wincol(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { validate_cursor(); - retvar->var_val.var_number = curwin->w_wcol + 1; + retvar->vval.v_number = curwin->w_wcol + 1; } /* @@ -8196,16 +9002,16 @@ f_wincol(argvars, retvar) */ static void f_winheight(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { win_T *wp; wp = find_win_by_nr(&argvars[0]); if (wp == NULL) - retvar->var_val.var_number = -1; - else - retvar->var_val.var_number = wp->w_height; + retvar->vval.v_number = -1; + else + retvar->vval.v_number = wp->w_height; } /* @@ -8214,11 +9020,11 @@ f_winheight(argvars, retvar) /*ARGSUSED*/ static void f_winline(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { validate_cursor(); - retvar->var_val.var_number = curwin->w_wrow + 1; + retvar->vval.v_number = curwin->w_wrow + 1; } /* @@ -8227,8 +9033,8 @@ f_winline(argvars, retvar) /* ARGSUSED */ static void f_winnr(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { int nr = 1; #ifdef FEAT_WINDOWS @@ -8236,9 +9042,9 @@ f_winnr(argvars, retvar) win_T *twin = curwin; char_u *arg; - if (argvars[0].var_type != VAR_UNKNOWN) - { - arg = get_var_string(&argvars[0]); + if (argvars[0].v_type != VAR_UNKNOWN) + { + arg = get_vartv_string(&argvars[0]); if (STRCMP(arg, "$") == 0) twin = lastwin; else if (STRCMP(arg, "#") == 0) @@ -8258,7 +9064,7 @@ f_winnr(argvars, retvar) for (wp = firstwin; wp != twin; wp = wp->w_next) ++nr; #endif - retvar->var_val.var_number = nr; + retvar->vval.v_number = nr; } /* @@ -8267,8 +9073,8 @@ f_winnr(argvars, retvar) /* ARGSUSED */ static void f_winrestcmd(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { #ifdef FEAT_WINDOWS win_T *wp; @@ -8289,11 +9095,11 @@ f_winrestcmd(argvars, retvar) } ga_append(&ga, NUL); - retvar->var_val.var_string = ga.ga_data; + retvar->vval.v_string = ga.ga_data; #else - retvar->var_val.var_string = NULL; -#endif - retvar->var_type = VAR_STRING; + retvar->vval.v_string = NULL; +#endif + retvar->v_type = VAR_STRING; } /* @@ -8301,32 +9107,32 @@ f_winrestcmd(argvars, retvar) */ static void f_winwidth(argvars, retvar) - VAR argvars; - VAR retvar; + typeval *argvars; + typeval *retvar; { win_T *wp; wp = find_win_by_nr(&argvars[0]); if (wp == NULL) - retvar->var_val.var_number = -1; + retvar->vval.v_number = -1; else #ifdef FEAT_VERTSPLIT - retvar->var_val.var_number = wp->w_width; + retvar->vval.v_number = wp->w_width; #else - retvar->var_val.var_number = Columns; + retvar->vval.v_number = Columns; #endif } static win_T * find_win_by_nr(vp) - VAR vp; + typeval *vp; { #ifdef FEAT_WINDOWS win_T *wp; #endif int nr; - nr = get_var_number(vp); + nr = get_vartv_number(vp); #ifdef FEAT_WINDOWS if (nr == 0) @@ -8348,14 +9154,14 @@ find_win_by_nr(vp) */ static pos_T * var2fpos(varp, lnum) - VAR varp; + typeval *varp; int lnum; /* TRUE when $ is last line */ { char_u *name; static pos_T pos; pos_T *pp; - name = get_var_string(varp); + name = get_vartv_string(varp); if (name[0] == '.') /* cursor */ return &curwin->w_cursor; if (name[0] == '\'') /* mark */ @@ -8750,19 +9556,19 @@ set_cmdarg(eap, oldarg) * Return OK or FAIL. */ static int -get_var_var(name, len, retvar) +get_var_vartv(name, len, retvar) char_u *name; int len; /* length of "name" */ - VAR retvar; /* NULL when only checking existence */ + typeval *retvar; /* NULL when only checking existence */ { int ret = OK; - int type = VAR_UNKNOWN; - long number = 1; - char_u *string = NULL; + typeval tv; VAR v; int cc; int i; + tv.v_type = VAR_UNKNOWN; + /* truncate the name, so that we can use strcmp() */ cc = name[len]; name[len] = NUL; @@ -8772,8 +9578,8 @@ get_var_var(name, len, retvar) */ if (STRCMP(name, "b:changedtick") == 0) { - type = VAR_NUMBER; - number = curbuf->b_changedtick; + tv.v_type = VAR_NUMBER; + tv.vval.v_number = curbuf->b_changedtick; } /* @@ -8781,9 +9587,11 @@ get_var_var(name, len, retvar) */ else if ((i = find_vim_var(name, len)) >= 0) { - type = vimvars[i].type; - number = (long)vimvars[i].val; - string = vimvars[i].val; + tv.v_type = vimvars[i].type; + if (tv.v_type == VAR_NUMBER) + tv.vval.v_number = (long)vimvars[i].val; + else + tv.vval.v_string = vimvars[i].val; } /* @@ -8793,31 +9601,17 @@ get_var_var(name, len, retvar) { v = find_var(name, FALSE); if (v != NULL) - { - type = v->var_type; - number = v->var_val.var_number; - string = v->var_val.var_string; - } - } - - if (type == VAR_UNKNOWN) + tv = v->tv; + } + + if (tv.v_type == VAR_UNKNOWN) { if (retvar != NULL) EMSG2(_("E121: Undefined variable: %s"), name); ret = FAIL; } else if (retvar != NULL) - { - retvar->var_type = type; - if (type == VAR_NUMBER) - retvar->var_val.var_number = number; - else if (type == VAR_STRING) - { - if (string != NULL) - string = vim_strsave(string); - retvar->var_val.var_string = string; - } - } + copy_vartv(&tv, retvar); name[len] = cc; @@ -8834,21 +9628,31 @@ alloc_var() } /* - * Allocate memory for a variable, and assign a string to it. + * Allocate memory for a variable type-value, and make it emtpy (0 or NULL + * value). + */ + static typeval * +alloc_vartv() +{ + return (typeval *)alloc_clear((unsigned)sizeof(typeval)); +} + +/* + * Allocate memory for a variable type-value, and assign a string to it. * The string "s" must have been allocated, it is consumed. * Return NULL for out of memory, the variable otherwise. */ - static VAR -alloc_string_var(s) + static typeval * +alloc_string_vartv(s) char_u *s; { - VAR retvar; - - retvar = alloc_var(); + typeval *retvar; + + retvar = alloc_vartv(); if (retvar != NULL) { - retvar->var_type = VAR_STRING; - retvar->var_val.var_string = s; + retvar->v_type = VAR_STRING; + retvar->vval.v_string = s; } else vim_free(s); @@ -8856,17 +9660,26 @@ alloc_string_var(s) } /* - * Free the memory for a variable. - */ - static void -free_var(varp) - VAR varp; + * Free the memory for a variable type-value. + */ + static void +free_vartv(varp) + typeval *varp; { if (varp != NULL) { - if (varp->var_type == VAR_STRING) - vim_free(varp->var_val.var_string); - vim_free(varp->var_name); + switch (varp->v_type) + { + case VAR_STRING: + case VAR_FUNC: + vim_free(varp->vval.v_string); + break; + case VAR_LIST: + list_unref(varp->vval.v_list); + break; + default: + break; + } vim_free(varp); } } @@ -8875,18 +9688,25 @@ free_var(varp) * Free the memory for a variable value and set the value to NULL or 0. */ static void -clear_var(varp) - VAR varp; +clear_vartv(varp) + typeval *varp; { if (varp != NULL) { - if (varp->var_type == VAR_STRING) - { - vim_free(varp->var_val.var_string); - varp->var_val.var_string = NULL; - } - else - varp->var_val.var_number = 0; + switch (varp->v_type) + { + case VAR_STRING: + case VAR_FUNC: + vim_free(varp->vval.v_string); + varp->vval.v_string = NULL; + break; + case VAR_LIST: + list_unref(varp->vval.v_list); + break; + default: + varp->vval.v_number = 0; + break; + } } } @@ -8895,39 +9715,47 @@ clear_var(varp) * If it is a String variable, uses vim_str2nr(). */ static long -get_var_number(varp) - VAR varp; -{ - long n; - - if (varp->var_type == VAR_NUMBER) - return (long)(varp->var_val.var_number); - else if (varp->var_type == VAR_UNKNOWN || varp->var_val.var_string == NULL) - return 0L; - else - { - vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL); - return n; - } +get_vartv_number(varp) + typeval *varp; +{ + long n = 0L; + + switch (varp->v_type) + { + case VAR_NUMBER: + n = (long)(varp->vval.v_number); + break; + case VAR_FUNC: + EMSG(_("E999: Using function reference as a number")); + break; + case VAR_STRING: + if (varp->vval.v_string != NULL) + vim_str2nr(varp->vval.v_string, NULL, NULL, + TRUE, TRUE, &n, NULL); + break; + default: + break; + } + return n; } /* * Get the lnum from the first argument. Also accepts ".", "$", etc. */ static linenr_T -get_var_lnum(argvars) - VAR argvars; -{ - var retvar; +get_vartv_lnum(argvars) + typeval *argvars; +{ + typeval retvar; linenr_T lnum; - lnum = get_var_number(&argvars[0]); + lnum = get_vartv_number(&argvars[0]); if (lnum == 0) /* no valid number, try using line() */ { - retvar.var_type = VAR_NUMBER; + retvar.v_type = VAR_NUMBER; f_line(argvars, &retvar); - lnum = retvar.var_val.var_number; - clear_var(&retvar); + lnum = retvar.vval.v_number; + clear_vartv(&retvar); } return lnum; } @@ -8941,33 +9769,45 @@ get_var_lnum(argvars) * Never returns NULL; */ static char_u * -get_var_string(varp) - VAR varp; +get_vartv_string(varp) + typeval *varp; { static char_u mybuf[NUMBUFLEN]; - return get_var_string_buf(varp, mybuf); + return get_vartv_string_buf(varp, mybuf); } static char_u * -get_var_string_buf(varp, buf) - VAR varp; - char_u *buf; -{ - if (varp->var_type == VAR_NUMBER) - { - sprintf((char *)buf, "%ld", (long)varp->var_val.var_number); - return buf; - } - else if (varp->var_val.var_string == NULL) - return (char_u *)""; - else - return varp->var_val.var_string; +get_vartv_string_buf(varp, buf) + typeval *varp; + char_u *buf; +{ + switch (varp->v_type) + { + case VAR_NUMBER: + sprintf((char *)buf, "%ld", (long)varp->vval.v_number); + return buf; + case VAR_FUNC: + EMSG(_("E99: using Funcref as a String")); + break; + case VAR_LIST: + EMSG(_("E99: using List as a String")); + break; + case VAR_STRING: + if (varp->vval.v_string != NULL) + return varp->vval.v_string; + break; + default: + EMSG(_("E999: Internal error: get_vartv_string_buf()")); + break; + } + return (char_u *)""; } /* * Find variable "name" in the list of variables. * Return a pointer to it if found, NULL if not found. + * Careful: "a:0" variables don't have a name. */ static VAR find_var(name, writing) @@ -8978,9 +9818,11 @@ find_var(name, writing) char_u *varname; garray_T *gap; - /* Check for function arguments "a:" */ if (name[0] == 'a' && name[1] == ':') { + /* Function arguments "a:". + * NOTE: We use a typecast, because function arguments don't have a + * name. The caller must not try to access the name! */ if (writing) { EMSG2(_(e_readonlyvar), name); @@ -8997,7 +9839,7 @@ find_var(name, writing) i += current_funccal->func->args.ga_len; if (i > current_funccal->argcount) /* a:999 */ return NULL; - return &(current_funccal->argvars[i - 1]); /* a:1, a:2, etc. */ + return (VAR)&(current_funccal->argvars[i - 1]); /* a:1, a:2, etc. */ } if (STRCMP(name, "firstline") == 0) return &(current_funccal->firstline); @@ -9006,7 +9848,7 @@ find_var(name, writing) for (i = 0; i < current_funccal->func->args.ga_len; ++i) if (STRCMP(name, ((char_u **) (current_funccal->func->args.ga_data))[i]) == 0) - return &(current_funccal->argvars[i]); /* a:name */ + return (VAR)&(current_funccal->argvars[i]); /* a:name */ return NULL; } @@ -9024,8 +9866,8 @@ find_var_in_ga(gap, varname) int i; for (i = gap->ga_len; --i >= 0; ) - if (VAR_GAP_ENTRY(i, gap).var_name != NULL - && STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0) + if (VAR_GAP_ENTRY(i, gap).v_name != NULL + && STRCMP(VAR_GAP_ENTRY(i, gap).v_name, varname) == 0) break; if (i < 0) return NULL; @@ -9093,7 +9935,7 @@ new_script_vars(id) { while (ga_scripts.ga_len < id) { - var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1)); + vars_init(&SCRIPT_VARS(ga_scripts.ga_len + 1)); ++ga_scripts.ga_len; } } @@ -9103,7 +9945,7 @@ new_script_vars(id) * Initialize internal variables for use. */ void -var_init(gap) +vars_init(gap) garray_T *gap; { ga_init2(gap, (int)sizeof(var), 4); @@ -9113,25 +9955,23 @@ var_init(gap) * Clean up a list of internal variables. */ void -var_clear(gap) +vars_clear(gap) garray_T *gap; { int i; for (i = gap->ga_len; --i >= 0; ) - var_free_one(&VAR_GAP_ENTRY(i, gap)); + clear_var(&VAR_GAP_ENTRY(i, gap)); ga_clear(gap); } static void -var_free_one(v) +clear_var(v) VAR v; { - vim_free(v->var_name); - v->var_name = NULL; - if (v->var_type == VAR_STRING) - vim_free(v->var_val.var_string); - v->var_val.var_string = NULL; + vim_free(v->v_name); + v->v_name = NULL; + clear_vartv(&v->tv); } /* @@ -9142,7 +9982,13 @@ list_one_var(v, prefix) VAR v; char_u *prefix; { - list_one_var_a(prefix, v->var_name, v->var_type, get_var_string(v)); + char_u *tofree; + char_u *s; + + s = tv2string(&v->tv, &tofree); + list_one_var_a(prefix, v->v_name, v->tv.v_type, + s == NULL ? (char_u *)"" : s); + vim_free(tofree); } /* @@ -9182,9 +10028,21 @@ list_one_var_a(prefix, name, type, strin msg_advance(22); if (type == VAR_NUMBER) msg_putchar('#'); + else if (type == VAR_FUNC) + msg_putchar('*'); + else if (type == VAR_LIST) + { + msg_putchar('['); + if (*string == '[') + ++string; + } else msg_putchar(' '); + msg_outtrans(string); + + if (type == VAR_FUNC) + msg_puts((char_u *)"()"); } /* @@ -9195,7 +10053,7 @@ list_one_var_a(prefix, name, type, strin static void set_var(name, varp, copy) char_u *name; - VAR varp; + typeval *varp; int copy; /* make copy of value in "varp" */ { int i; @@ -9218,26 +10076,51 @@ set_var(name, varp, copy) if (vimvars[i].type == VAR_STRING) { vim_free(vimvars[i].val); - if (copy || varp->var_type != VAR_STRING) - vimvars[i].val = vim_strsave(get_var_string(varp)); + if (copy || varp->v_type != VAR_STRING) + vimvars[i].val = vim_strsave(get_vartv_string(varp)); else { /* Take over the string to avoid an extra alloc/free. */ - vimvars[i].val = varp->var_val.var_string; - varp->var_val.var_string = NULL; + vimvars[i].val = varp->vval.v_string; + varp->vval.v_string = NULL; } } else - vimvars[i].val = (char_u *)get_var_number(varp); + vimvars[i].val = (char_u *)get_vartv_number(varp); } return; } + if (varp->v_type == VAR_FUNC) + { + if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') + && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') + ? name[2] : name[0])) + { + EMSG2(_("E999: Funcref variable name must start with a capital: %s"), name); + return; + } + if (function_exists(name)) + { + EMSG2(_("E999: Variable name conflicts with existing function: %s"), name); + return; + } + } + v = find_var(name, TRUE); if (v != NULL) /* existing variable, only need to free string */ { - if (v->var_type == VAR_STRING) - vim_free(v->var_val.var_string); + if (v->tv.v_type != varp->v_type + && !((v->tv.v_type == VAR_STRING + || v->tv.v_type == VAR_NUMBER) + && (varp->v_type == VAR_STRING + || varp->v_type == VAR_NUMBER))) + { + EMSG2(_("E999: Variable type mismatch for: %s"), name); + return; + } + if (v->tv.v_type == VAR_STRING || v->tv.v_type == VAR_FUNC) + vim_free(v->tv.vval.v_string); } else /* add a new variable */ { @@ -9250,7 +10133,7 @@ set_var(name, varp, copy) /* Try to use an empty entry */ for (i = gap->ga_len; --i >= 0; ) - if (VAR_GAP_ENTRY(i, gap).var_name == NULL) + if (VAR_GAP_ENTRY(i, gap).v_name == NULL) break; if (i < 0) /* need to allocate more room */ { @@ -9259,30 +10142,57 @@ set_var(name, varp, copy) i = gap->ga_len; } v = &VAR_GAP_ENTRY(i, gap); - if ((v->var_name = vim_strsave(varname)) == NULL) + if ((v->v_name = vim_strsave(varname)) == NULL) return; if (i == gap->ga_len) ++gap->ga_len; } - if (copy || varp->var_type != VAR_STRING) - copy_var(varp, v); - else - { - v->var_type = varp->var_type; - v->var_val.var_string = varp->var_val.var_string; - } -} - - static void -copy_var(from, to) - VAR from; - VAR to; -{ - to->var_type = from->var_type; - if (from->var_type == VAR_STRING) - to->var_val.var_string = vim_strsave(get_var_string(from)); - else - to->var_val.var_number = from->var_val.var_number; + if (copy || (varp->v_type != VAR_STRING && varp->v_type != VAR_FUNC)) + copy_vartv(varp, &v->tv); + else + { + v->tv.v_type = varp->v_type; + v->tv.vval.v_string = varp->vval.v_string; + varp->vval.v_string = NULL; + } +} + +/* + * Copy the values from typeval "from" to typeval "to". + * When needed allocates string or increases reference count. + * Does not make a copy of a list! + */ + static void +copy_vartv(from, to) + typeval *from; + typeval *to; +{ + to->v_type = from->v_type; + switch (from->v_type) + { + case VAR_NUMBER: + to->vval.v_number = from->vval.v_number; + break; + case VAR_STRING: + case VAR_FUNC: + if (from->vval.v_string == NULL) + to->vval.v_string = NULL; + else + to->vval.v_string = vim_strsave(from->vval.v_string); + break; + case VAR_LIST: + if (from->vval.v_list == NULL) + to->vval.v_list = NULL; + else + { + to->vval.v_list = from->vval.v_list; + ++to->vval.v_list->lv_refcount; + } + break; + default: + EMSG(_("E999: Internal error: copy_vartv()")); + break; + } } /* @@ -9295,7 +10205,8 @@ ex_echo(eap) exarg_T *eap; { char_u *arg = eap->arg; - var retvar; + typeval retvar; + char_u *tofree; char_u *p; int needclr = TRUE; int atstart = TRUE; @@ -9328,7 +10239,7 @@ ex_echo(eap) } else if (eap->cmdidx == CMD_echo) msg_puts_attr((char_u *)" ", echo_attr); - for (p = get_var_string(&retvar); *p != NUL && !got_int; ++p) + for (p = tv2string(&retvar, &tofree); *p != NUL && !got_int; ++p) if (*p == '\n' || *p == '\r' || *p == TAB) { if (*p != TAB && needclr) @@ -9353,8 +10264,9 @@ ex_echo(eap) #endif (void)msg_outtrans_len_attr(p, 1, echo_attr); } - } - clear_var(&retvar); + vim_free(tofree); + } + clear_vartv(&retvar); arg = skipwhite(arg); } eap->nextcmd = check_nextcmd(arg); @@ -9399,7 +10311,7 @@ ex_execute(eap) exarg_T *eap; { char_u *arg = eap->arg; - var retvar; + typeval retvar; int ret = OK; char_u *p; garray_T ga; @@ -9428,11 +10340,11 @@ ex_execute(eap) if (!eap->skip) { - p = get_var_string(&retvar); + p = get_vartv_string(&retvar); len = (int)STRLEN(p); if (ga_grow(&ga, len + 2) == FAIL) { - clear_var(&retvar); + clear_vartv(&retvar); ret = FAIL; break; } @@ -9442,7 +10354,7 @@ ex_execute(eap) ga.ga_len += len; } - clear_var(&retvar); + clear_vartv(&retvar); arg = skipwhite(arg); } @@ -9536,6 +10448,7 @@ ex_function(eap) int nesting; char_u *skip_until = NULL; static char_u e_funcexts[] = N_("E122: Function %s already exists, add ! to replace it"); + VAR v; /* * ":function" without argument: list functions. @@ -9830,6 +10743,13 @@ ex_function(eap) /* * If there are no errors, add the function */ + v = find_var(name, FALSE); + if (v != NULL && v->tv.v_type == VAR_FUNC) + { + EMSG2(_("E999: Function name conflicts with variable: %s"), name); + goto erret; + } + fp = find_func(name); if (fp != NULL) { @@ -10065,6 +10985,28 @@ find_func(name) return fp; } +/* + * Return TRUE if a function "name" exists. + */ + static int +function_exists(name) + char_u *name; +{ + char_u *p = name; + int n = FALSE; + + p = trans_function_name(&p, FALSE, TRUE); + if (p != NULL) + { + if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL) + n = (find_func(p) != NULL); + else if (ASCII_ISLOWER(*p)) + n = (find_internal_func(p) >= 0); + vim_free(p); + } + return n; +} + #if defined(FEAT_CMDL_COMPL) || defined(PROTO) /* @@ -10190,8 +11132,8 @@ ex_delfunction(eap) call_user_func(fp, argcount, argvars, retvar, firstline, lastline) ufunc_T *fp; /* pointer to function */ int argcount; /* nr of args */ - VAR argvars; /* arguments */ - VAR retvar; /* return value */ + typeval *argvars; /* arguments */ + typeval *retvar; /* return value */ linenr_T firstline; /* first line of range */ linenr_T lastline; /* last line of range */ { @@ -10207,8 +11149,8 @@ call_user_func(fp, argcount, argvars, re if (depth >= p_mfd) { EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = -1; + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = -1; return; } ++depth; @@ -10216,25 +11158,25 @@ call_user_func(fp, argcount, argvars, re line_breakcheck(); /* check for CTRL-C hit */ /* set local variables */ - var_init(&fc.l_vars); + vars_init(&fc.l_vars); fc.func = fp; fc.argcount = argcount; fc.argvars = argvars; fc.retvar = retvar; - retvar->var_val.var_number = 0; + retvar->vval.v_number = 0; fc.linenr = 0; fc.returned = FALSE; fc.level = ex_nesting_level; - fc.a0_var.var_type = VAR_NUMBER; - fc.a0_var.var_val.var_number = argcount - fp->args.ga_len; - fc.a0_var.var_name = NULL; + fc.a0_var.tv.v_type = VAR_NUMBER; + fc.a0_var.tv.vval.v_number = argcount - fp->args.ga_len; + fc.a0_var.v_name = NULL; current_funccal = &fc; - fc.firstline.var_type = VAR_NUMBER; - fc.firstline.var_val.var_number = firstline; - fc.firstline.var_name = NULL; - fc.lastline.var_type = VAR_NUMBER; - fc.lastline.var_val.var_number = lastline; - fc.lastline.var_name = NULL; + fc.firstline.tv.v_type = VAR_NUMBER; + fc.firstline.tv.vval.v_number = firstline; + fc.firstline.v_name = NULL; + fc.lastline.tv.v_type = VAR_NUMBER; + fc.lastline.tv.vval.v_number = lastline; + fc.lastline.v_name = NULL; /* Check if this function has a breakpoint. */ fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0); fc.dbg_tick = debug_tick; @@ -10270,11 +11212,11 @@ call_user_func(fp, argcount, argvars, re { if (i > 0) msg_puts((char_u *)", "); - if (argvars[i].var_type == VAR_NUMBER) - msg_outnum((long)argvars[i].var_val.var_number); + if (argvars[i].v_type == VAR_NUMBER) + msg_outnum((long)argvars[i].vval.v_number); else { - trunc_string(get_var_string(&argvars[i]), + trunc_string(get_vartv_string(&argvars[i]), buf, MSG_BUF_LEN); msg_puts((char_u *)"\""); msg_puts(buf); @@ -10300,11 +11242,11 @@ call_user_func(fp, argcount, argvars, re --RedrawingDisabled; /* when the function was aborted because of an error, return -1 */ - if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->var_type == VAR_UNKNOWN) - { - clear_var(retvar); - retvar->var_type = VAR_NUMBER; - retvar->var_val.var_number = -1; + if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->v_type == VAR_UNKNOWN) + { + clear_vartv(retvar); + retvar->v_type = VAR_NUMBER; + retvar->vval.v_number = -1; } /* when being verbose, mention the return value */ @@ -10322,12 +11264,12 @@ call_user_func(fp, argcount, argvars, re if (aborting()) smsg((char_u *)_("%s aborted"), sn); - else if (fc.retvar->var_type == VAR_NUMBER) + else if (fc.retvar->v_type == VAR_NUMBER) smsg((char_u *)_("%s returning #%ld"), sn, - (long)fc.retvar->var_val.var_number); - else if (fc.retvar->var_type == VAR_STRING) - { - val = get_var_string(fc.retvar); + (long)fc.retvar->vval.v_number); + else if (fc.retvar->v_type == VAR_STRING) + { + val = get_vartv_string(fc.retvar); if (STRLEN(val) > IOSIZE / 2 - 50) val = val + STRLEN(val) - (IOSIZE / 2 - 50); smsg((char_u *)_("%s returning \"%s\""), sn, val); @@ -10355,7 +11297,7 @@ call_user_func(fp, argcount, argvars, re did_emsg |= save_did_emsg; current_funccal = save_fcp; - var_clear(&fc.l_vars); /* free all local variables */ + vars_clear(&fc.l_vars); /* free all local variables */ --depth; } @@ -10386,7 +11328,7 @@ ex_return(eap) if (!eap->skip) returning = do_return(eap, FALSE, TRUE, &retvar); else - clear_var(&retvar); + clear_vartv(&retvar.tv); } /* It's safer to return also on error. */ else if (!eap->skip) @@ -10460,7 +11402,7 @@ do_return(eap, reanimate, is_cmd, value) { /* Store the value of the pending return. */ if ((cstack->cs_retvar[idx] = alloc_var()) != NULL) - *(VAR)cstack->cs_retvar[idx] = *(VAR)value; + *(typeval *)cstack->cs_retvar[idx] = *(typeval *)value; else EMSG(_(e_outofmem)); } @@ -10472,8 +11414,8 @@ do_return(eap, reanimate, is_cmd, value) /* The pending return value could be overwritten by a ":return" * without argument in a finally clause; reset the default * return value. */ - current_funccal->retvar->var_type = VAR_NUMBER; - current_funccal->retvar->var_val.var_number = 0; + current_funccal->retvar->v_type = VAR_NUMBER; + current_funccal->retvar->vval.v_number = 0; } } report_make_pending(CSTP_RETURN, value); @@ -10487,8 +11429,8 @@ do_return(eap, reanimate, is_cmd, value) * there. */ if (!reanimate && value != NULL) { - clear_var(current_funccal->retvar); - *current_funccal->retvar = *(VAR)value; + clear_vartv(current_funccal->retvar); + *current_funccal->retvar = *(typeval *)value; if (!is_cmd) vim_free(value); } @@ -10504,9 +11446,9 @@ do_return(eap, reanimate, is_cmd, value) discard_pending_return(retvar) void *retvar; { - /* The variable was copied from one with an undefined var_name. So we can't - * use free_var() to clear and free it. */ - clear_var((VAR)retvar); + /* The variable was copied from one with an undefined v_name. So we can't + * use free_vartv() to clear and free it. */ + clear_vartv(&((VAR)retvar)->tv); vim_free(retvar); } @@ -10520,14 +11462,14 @@ get_return_cmd(retvar) { char_u *s = IObuff; - if (retvar == NULL || ((VAR)retvar)->var_type == VAR_UNKNOWN) + if (retvar == NULL || ((VAR)retvar)->tv.v_type == VAR_UNKNOWN) s = (char_u *)":return"; - else if (((VAR)retvar)->var_type == VAR_STRING) + else if (((VAR)retvar)->tv.v_type == VAR_STRING) sprintf((char *)IObuff, ":return \"%s\"", - ((VAR)retvar)->var_val.var_string); + ((VAR)retvar)->tv.vval.v_string); else sprintf((char *)IObuff, ":return %ld", - (long)(((VAR)retvar)->var_val.var_number)); + (long)(((VAR)retvar)->tv.vval.v_number)); return vim_strsave(s); } @@ -10644,7 +11586,7 @@ read_viminfo_varlist(virp, writing) { char_u *tab; int is_string = FALSE; - VAR varp = NULL; + typeval *vartvp = NULL; char_u *val; if (!writing && (find_viminfo_parameter('!') != NULL)) @@ -10665,22 +11607,22 @@ read_viminfo_varlist(virp, writing) val = viminfo_readstring(virp, (int)(tab - virp->vir_line + 1), TRUE); if (val != NULL) - varp = alloc_string_var(val); + vartvp = alloc_string_vartv(val); } else { - varp = alloc_var(); - if (varp != NULL) + vartvp = alloc_vartv(); + if (vartvp != NULL) { - varp->var_type = VAR_NUMBER; - varp->var_val.var_number = atol((char *)tab + 1); + vartvp->v_type = VAR_NUMBER; + vartvp->vval.v_number = atol((char *)tab + 1); } } /* assign the value to the variable */ - if (varp != NULL) + if (vartvp != NULL) { - set_var(virp->vir_line + 1, varp, FALSE); - free_var(varp); + set_var(virp->vir_line + 1, vartvp, FALSE); + free_vartv(vartvp); } } } @@ -10707,11 +11649,11 @@ write_viminfo_varlist(fp) for (i = gap->ga_len; --i >= 0; ) { this_var = &VAR_GAP_ENTRY(i, gap); - if (this_var->var_name != NULL - && var_flavour(this_var->var_name) == VAR_FLAVOUR_VIMINFO) - { - fprintf(fp, "!%s\t%s\t", this_var->var_name, - (this_var->var_type == VAR_STRING) ? "STR" : "NUM"); + if (this_var->v_name != NULL + && var_flavour(this_var->v_name) == VAR_FLAVOUR_VIMINFO) + { + fprintf(fp, "!%s\t%s\t", this_var->v_name, + (this_var->tv.v_type == VAR_STRING) ? "STR" : "NUM"); viminfo_writestring(fp, get_var_string(this_var)); } } @@ -10731,9 +11673,9 @@ store_session_globals(fd) for (i = gap->ga_len; --i >= 0; ) { this_var = &VAR_GAP_ENTRY(i, gap); - if (this_var->var_name != NULL) - { - if (var_flavour(this_var->var_name) == VAR_FLAVOUR_SESSION) + if (this_var->v_name != NULL) + { + if (var_flavour(this_var->v_name) == VAR_FLAVOUR_SESSION) { /* Escapse special characters with a backslash. Turn a LF and * CR into \n and \r. */ @@ -10747,10 +11689,10 @@ store_session_globals(fd) else if (*t == '\r') *t = 'r'; if ((fprintf(fd, "let %s = %c%s%c", - this_var->var_name, - (this_var->var_type == VAR_STRING) ? '"' : ' ', - p, - (this_var->var_type == VAR_STRING) ? '"' : ' ') < 0) + this_var->v_name, + (this_var->tv.v_type == VAR_STRING) ? '"' : ' ', + p, + (this_var->tv.v_type == VAR_STRING) ? '"' : ' ') < 0) || put_eol(fd) == FAIL) { vim_free(p);