diff options
author | Bram Moolenaar <Bram@vim.org> | 2005-01-25 22:26:29 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2005-01-25 22:26:29 +0000 |
commit | 33570924ba5a228eb5b7f015459bedfb8f8f26fd (patch) | |
tree | d172e388e8319ba4e551f23ffc87e215a680cc6a | |
parent | b71ec9fc70b9b64af1a70c73f4b9b9c70f389b54 (diff) |
updated for version 7.0044v7.0044
-rw-r--r-- | src/eval.c | 3167 | ||||
-rw-r--r-- | src/gui_beval.c | 2 | ||||
-rw-r--r-- | src/if_mzsch.c | 323 | ||||
-rwxr-xr-x | src/link.sh | 2 | ||||
-rw-r--r-- | src/testdir/test.ok | 32 |
5 files changed, 1904 insertions, 1622 deletions
diff --git a/src/eval.c b/src/eval.c index 50298e9f4b..1ef824b152 100644 --- a/src/eval.c +++ b/src/eval.c @@ -30,131 +30,21 @@ #if defined(FEAT_EVAL) || defined(PROTO) -#if SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */ -typedef long varnumber_T; -#else -typedef int varnumber_T; -#endif - -/* - * 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!) */ - struct dictvar_S *v_dict; /* dict 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 */ -#define VAR_DICT 5 /* "v_dict" 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 -{ - typeval tv; /* type and value of the variable */ - char_u v_name[1]; /* name of variable (actually longer) */ -} var; - -typedef var * VAR; - -/* - * In a hashtable item "hi_key" points to "v_name" in a variable. - * This avoids adding a pointer to the hashtable item. - * VAR2HIKEY() converts a var pointer to a hashitem key pointer. - * HIKEY2VAR() converts a hashitem key pointer to a var pointer. - * HI2VAR() converts a hashitem pointer to a var pointer. - */ -static var dumvar; -#define VAR2HIKEY(v) ((v)->v_name) -#define HIKEY2VAR(p) ((VAR)(p - (dumvar.v_name - (char_u *)&dumvar.tv))) -#define HI2VAR(hi) HIKEY2VAR((hi)->hi_key) - -/* - * 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; +#define DICT_MAXNEST 100 /* maximum nesting of lists and dicts */ /* - * Struct used by those that are using an item in a list. - */ -typedef struct listwatch_S -{ - listitem *lw_item; /* item being watched */ - struct listwatch_S *lw_next; /* next watcher */ -} listwatch; - -/* - * Structure to hold 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 */ - listwatch *lv_watch; /* first watcher, NULL if none */ -}; - -typedef struct listvar_S listvar; - -#define VAR_MAXNEST 100 /* maximum nesting of lists and dicts */ - -/* - * Structure to hold an item of a Dictionary. - * The key is copied into "di_key" to avoid an extra alloc/free for it. - */ -struct dictitem_S -{ - typeval di_tv; /* type and value of the variable */ - char_u di_key[1]; /* key (actually longer!) */ -}; - -typedef struct dictitem_S dictitem; - -/* - * In a hashtable item "hi_key" points to "di_key" in a dictitem. - * This avoids adding a pointer to the hashtable item. + * In a hashtab item "hi_key" points to "di_key" in a dictitem. + * This avoids adding a pointer to the hashtab item. * DI2HIKEY() converts a dictitem pointer to a hashitem key pointer. * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. * HI2DI() converts a hashitem pointer to a dictitem pointer. */ -static dictitem dumdi; +static dictitem_T dumdi; #define DI2HIKEY(di) ((di)->di_key) -#define HIKEY2DI(p) ((dictitem *)(p - (dumdi.di_key - (char_u *)&dumdi.di_tv))) +#define HIKEY2DI(p) ((dictitem_T *)(p - (dumdi.di_key - (char_u *)&dumdi))) #define HI2DI(hi) HIKEY2DI((hi)->hi_key) /* - * Structure to hold info about a Dictionary. - */ -struct dictvar_S -{ - int dv_refcount; /* reference count */ - hashtable dv_hashtable; /* hashtable that refers to the items */ -}; - -typedef struct dictvar_S dictvar; - -/* * Structure returned by get_lval() and used by set_var_lval(). * For a plain name: * "name" points to the variable name. @@ -178,26 +68,26 @@ typedef struct dictvar_S dictvar; * For a non-existing Dict item: * "name" points to the (expanded) variable name. * "exp_name" NULL or non-NULL, to be freed later. - * "tv" points to the Dictionary typeval + * "tv" points to the Dictionary typval_T * "newkey" is the key for the new item. */ typedef struct lval_S { char_u *ll_name; /* start of variable name (can be NULL) */ char_u *ll_exp_name; /* NULL or expanded name in allocated memory. */ - typeval *ll_tv; /* Typeval of item being used. If "newkey" + typval_T *ll_tv; /* Typeval of item being used. If "newkey" isn't NULL it's the Dict to which to add the item. */ - listitem *ll_li; /* The list item or NULL. */ - listvar *ll_list; /* The list or NULL. */ + listitem_T *ll_li; /* The list item or NULL. */ + list_T *ll_list; /* The list or NULL. */ int ll_range; /* TRUE when a [i:j] range was used */ long ll_n1; /* First index for list */ long ll_n2; /* Second index for list range */ int ll_empty2; /* Second index is empty: [i:] */ - dictvar *ll_dict; /* The Dictionary or NULL */ - dictitem *ll_di; /* The dictitem or NULL */ + dict_T *ll_dict; /* The Dictionary or NULL */ + dictitem_T *ll_di; /* The dictitem or NULL */ char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ -} lval; +} lval_T; static char *e_letunexp = N_("E18: Unexpected characters in :let"); @@ -218,15 +108,26 @@ static char *e_dictrange = N_("E719: Cannot use [:] with a Dictionary"); static char *e_letwrong = N_("E734: Wrong variable type for %s="); /* - * All user-defined global variables are stored in "variables". + * All user-defined global variables are stored in dictionary "globvardict". + * "globvars_var" is the variable that is used for "g:". */ -hashtable variables; +static dict_T globvardict; +static dictitem_T globvars_var; +#define globvarht globvardict.dv_hashtab /* - * Array to hold the hashtable with variables local to each sourced script. + * Array to hold the hashtab with variables local to each sourced script. + * Each item holds a variable (nameless) that points to the dict_T. */ -static garray_T ga_scripts = {0, 0, sizeof(hashtable), 4, NULL}; -#define SCRIPT_VARS(id) (((hashtable *)ga_scripts.ga_data)[(id) - 1]) +typedef struct +{ + dictitem_T sv_var; + dict_T sv_dict; +} scriptvar_T; + +static garray_T ga_scripts = {0, 0, sizeof(scriptvar_T), 4, NULL}; +#define SCRIPT_SV(id) (((scriptvar_T *)ga_scripts.ga_data)[(id) - 1]) +#define SCRIPT_VARS(id) (SCRIPT_SV(id).sv_dict.dv_hashtab) static int echo_attr = 0; /* attributes used for ":echo" */ @@ -268,53 +169,453 @@ ufunc_T *firstfunc = NULL; #define FUNCARG(fp, j) ((char_u **)(fp->args.ga_data))[j] #define FUNCLINE(fp, j) ((char_u **)(fp->lines.ga_data))[j] +#define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ +#define VAR_SHORT_LEN 20 /* short variable name length */ +#define FIXVAR_CNT 12 /* number of fixed variables */ + /* structure to hold info for a function that is currently being executed. */ -struct funccall +typedef struct funccall_S { ufunc_T *func; /* function being called */ int linenr; /* next line to be executed */ int returned; /* ":return" used */ - int argcount; /* nr of arguments */ - typeval *argvars; /* arguments */ - var a0_var; /* "a:0" variable */ - var firstline; /* "a:firstline" variable */ - var lastline; /* "a:lastline" variable */ - hashtable l_vars; /* local function variables */ - typeval *rettv; /* return value */ + struct /* fixed variables for arguments */ + { + dictitem_T var; /* variable (without room for name) */ + char_u room[VAR_SHORT_LEN]; /* room for the name */ + } fixvar[FIXVAR_CNT]; + dict_T l_vars; /* l: local function variables */ + dictitem_T l_vars_var; /* variable for l: scope */ + dict_T l_avars; /* a: argument variables */ + dictitem_T l_avars_var; /* variable for a: scope */ + list_T l_varlist; /* list for a:000 */ + listitem_T l_listitems[MAX_FUNC_ARGS]; /* listitems for a:000 */ + typval_T *rettv; /* return value */ 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 */ -}; +} funccall_T; /* * Info used by a ":for" loop. */ -typedef struct forinfo_S +typedef struct { int fi_semicolon; /* TRUE if ending in '; var]' */ int fi_varcount; /* nr of variables in the list */ - listwatch fi_lw; /* keep an eye on the item used. */ - listvar *fi_list; /* list being used */ -} forinfo; + listwatch_T fi_lw; /* keep an eye on the item used. */ + list_T *fi_list; /* list being used */ +} forinfo_T; /* * Struct used by trans_function_name() */ typedef struct { - dictvar *fd_dict; /* Dictionary used */ + dict_T *fd_dict; /* Dictionary used */ char_u *fd_newkey; /* new key in "dict" */ - dictitem *fd_di; /* Dictionary item used */ -} funcdict; + dictitem_T *fd_di; /* Dictionary item used */ +} funcdict_T; + + +/* + * Array to hold the value of v: variables. + * The value is in a dictitem, so that it can also be used in the v: scope. + * The reason to use this table anyway is for very quick access to the + * variables with the VV_ defines. + */ +#include "version.h" + +/* values for vv_flags: */ +#define VV_COMPAT 1 /* compatible, also used without "v:" */ +#define VV_RO 2 /* read-only */ +#define VV_RO_SBX 4 /* read-only in the sandbox*/ + +#define VV_NAME(s, t) s, sizeof(s) - 1, {{t}}, {0} + +static struct vimvar +{ + char *vv_name; /* name of variable, without v: */ + int vv_len; /* length of name */ + dictitem_T vv_di; /* value and name for key */ + char vv_filler[16]; /* space for LONGEST name below!!! */ + char vv_flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ +} vimvars[VV_LEN] = +{ + /* + * The order here must match the VV_ defines in vim.h! + * Initializing a union does not work, leave tv.vval empty to get zero's. + */ + {VV_NAME("count", VAR_NUMBER), VV_COMPAT+VV_RO}, + {VV_NAME("count1", VAR_NUMBER), VV_RO}, + {VV_NAME("prevcount", VAR_NUMBER), VV_RO}, + {VV_NAME("errmsg", VAR_STRING), VV_COMPAT}, + {VV_NAME("warningmsg", VAR_STRING), 0}, + {VV_NAME("statusmsg", VAR_STRING), 0}, + {VV_NAME("shell_error", VAR_NUMBER), VV_COMPAT+VV_RO}, + {VV_NAME("this_session", VAR_STRING), VV_COMPAT}, + {VV_NAME("version", VAR_NUMBER), VV_COMPAT+VV_RO}, + {VV_NAME("lnum", VAR_NUMBER), VV_RO_SBX}, + {VV_NAME("termresponse", VAR_STRING), VV_RO}, + {VV_NAME("fname", VAR_STRING), VV_RO}, + {VV_NAME("lang", VAR_STRING), VV_RO}, + {VV_NAME("lc_time", VAR_STRING), VV_RO}, + {VV_NAME("ctype", VAR_STRING), VV_RO}, + {VV_NAME("charconvert_from", VAR_STRING), VV_RO}, + {VV_NAME("charconvert_to", VAR_STRING), VV_RO}, + {VV_NAME("fname_in", VAR_STRING), VV_RO}, + {VV_NAME("fname_out", VAR_STRING), VV_RO}, + {VV_NAME("fname_new", VAR_STRING), VV_RO}, + {VV_NAME("fname_diff", VAR_STRING), VV_RO}, + {VV_NAME("cmdarg", VAR_STRING), VV_RO}, + {VV_NAME("foldstart", VAR_NUMBER), VV_RO_SBX}, + {VV_NAME("foldend", VAR_NUMBER), VV_RO_SBX}, + {VV_NAME("folddashes", VAR_STRING), VV_RO_SBX}, + {VV_NAME("foldlevel", VAR_NUMBER), VV_RO_SBX}, + {VV_NAME("progname", VAR_STRING), VV_RO}, + {VV_NAME("servername", VAR_STRING), VV_RO}, + {VV_NAME("dying", VAR_NUMBER), VV_RO}, + {VV_NAME("exception", VAR_STRING), VV_RO}, + {VV_NAME("throwpoint", VAR_STRING), VV_RO}, + {VV_NAME("register", VAR_STRING), VV_RO}, + {VV_NAME("cmdbang", VAR_NUMBER), VV_RO}, + {VV_NAME("insertmode", VAR_STRING), VV_RO}, + {VV_NAME("val", VAR_STRING), VV_RO}, + {VV_NAME("key", VAR_STRING), VV_RO}, +}; + +/* shorthand */ +#define vv_type vv_di.di_tv.v_type +#define vv_nr vv_di.di_tv.vval.v_number +#define vv_str vv_di.di_tv.vval.v_string +#define vv_tv vv_di.di_tv + +/* + * The v: variables are stored in dictionary "vimvardict". + * "vimvars_var" is the variable that is used for the "l:" scope. + */ +static dict_T vimvardict; +static dictitem_T vimvars_var; +#define vimvarht vimvardict.dv_hashtab + +static int eval0 __ARGS((char_u *arg, typval_T *rettv, char_u **nextcmd, int evaluate)); +static int eval1 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval2 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval3 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval4 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval5 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval6 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval7 __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int eval_index __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int get_option_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static list_T *list_alloc __ARGS((void)); +static void list_unref __ARGS((list_T *l)); +static void list_free __ARGS((list_T *l)); +static listitem_T *listitem_alloc __ARGS((void)); +static void listitem_free __ARGS((listitem_T *item)); +static void listitem_remove __ARGS((list_T *l, listitem_T *item)); +static long list_len __ARGS((list_T *l)); +static int list_equal __ARGS((list_T *l1, list_T *l2, int ic)); +static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic)); +static int tv_equal __ARGS((typval_T *tv1, typval_T *tv2, int ic)); +static int string_isa_number __ARGS((char_u *s)); +static listitem_T *list_find __ARGS((list_T *l, long n)); +static long list_idx_of_item __ARGS((list_T *l, listitem_T *item)); +static listitem_T *list_find_ext __ARGS((list_T *l, long *ip)); +static void list_append __ARGS((list_T *l, listitem_T *item)); +static int list_append_tv __ARGS((list_T *l, typval_T *tv)); +static int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item)); +static int list_extend __ARGS((list_T *l1, list_T *l2, listitem_T *bef)); +static int list_concat __ARGS((list_T *l1, list_T *l2, typval_T *tv)); +static list_T *list_copy __ARGS((list_T *orig, int deep)); +static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2)); +static char_u *list2string __ARGS((typval_T *tv)); +static void list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo)); + +static dict_T *dict_alloc __ARGS((void)); +static void dict_unref __ARGS((dict_T *d)); +static void dict_free __ARGS((dict_T *d)); +static dictitem_T *dictitem_alloc __ARGS((char_u *key)); +static dictitem_T *dictitem_copy __ARGS((dictitem_T *org)); +static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item)); +static void dictitem_free __ARGS((dictitem_T *item)); +static int dict_add __ARGS((dict_T *d, dictitem_T *item)); +static long dict_len __ARGS((dict_T *d)); +static dictitem_T *dict_find __ARGS((dict_T *d, char_u *key, int len)); +static char_u *dict2string __ARGS((typval_T *tv)); +static int get_dict_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); + +static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); +static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u *numbuf)); +static char_u *string_quote __ARGS((char_u *str, int function)); +static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate)); +static int find_internal_func __ARGS((char_u *name)); +static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); +static int get_func_tv __ARGS((char_u *name, int len, typval_T *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); +static int call_func __ARGS((char_u *name, int len, typval_T *rettv, int argcount, typval_T *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, dict_T *selfdict)); + +static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_argv __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_browse __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_browsedir __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_bufexists __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_buflisted __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_bufloaded __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_bufname __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_bufnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_bufwinnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_byte2line __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_byteidx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_call __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_col __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_confirm __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_copy __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_count __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_cscope_connection __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_cursor __ARGS((typval_T *argsvars, typval_T *rettv)); +static void f_deepcopy __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_delete __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_did_filetype __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_diff_filler __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_diff_hlID __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_empty __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_escape __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_eval __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_eventhandler __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_executable __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_exists __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_expand __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_extend __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_filereadable __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_filewritable __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_filter __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_finddir __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_findfile __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_fnamemodify __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foldclosed __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foldclosedend __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foldlevel __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foldtext __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foldtextresult __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_function __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_get __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getcwd __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getfontname __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getfperm __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getfsize __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getline __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getregtype __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getwinposx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getwinposy __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_getwinvar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_glob __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_globpath __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_has __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_has_key __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_hasmapto __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_histadd __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_histdel __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_histget __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_histnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_hlID __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_hlexists __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_hostname __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_iconv __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_indent __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_index __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_input __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_inputdialog __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_inputrestore __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_join __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_keys __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_len __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_libcall __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_libcallnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_line __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_line2byte __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_lispindent __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_localtime __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_map __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_match __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_prevnonblank __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); +#ifdef HAVE_STRFTIME +static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); +#endif +static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); + +static win_T *find_win_by_nr __ARGS((typval_T *vp)); +static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); +static int get_env_len __ARGS((char_u **arg)); +static int get_id_len __ARGS((char_u **arg)); +static int get_name_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, int incl_br)); +static int eval_isnamec __ARGS((int c)); +static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv)); +static typval_T *alloc_tv __ARGS((void)); +static typval_T *alloc_string_tv __ARGS((char_u *string)); +static void free_tv __ARGS((typval_T *varp)); +static void clear_tv __ARGS((typval_T *varp)); +static void init_tv __ARGS((typval_T *varp)); +static long get_tv_number __ARGS((typval_T *varp)); +static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); +static char_u *get_tv_string __ARGS((typval_T *varp)); +static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); +static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); +static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname)); +static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); +static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); +static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); +static void list_one_var __ARGS((dictitem_T *v, char_u *prefix)); +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, typval_T *varp, int copy)); +static int var_check_ro __ARGS((int flags, char_u *name)); +static void copy_tv __ARGS((typval_T *from, typval_T *to)); +static void item_copy __ARGS((typval_T *from, typval_T *to, int deep)); +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 flags, funcdict_T *fd)); +static int eval_fname_script __ARGS((char_u *p)); +static int eval_fname_sid __ARGS((char_u *p)); +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 int function_exists __ARGS((char_u *name)); +static void func_free __ARGS((ufunc_T *fp)); +static void func_unref __ARGS((char_u *name)); +static void func_ref __ARGS((char_u *name)); +static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T *selfdict)); +static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr)); +static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); + +static int ex_let_vars __ARGS((char_u *arg, typval_T *tv, int copy, int semicolon, int var_count, char_u *nextchars)); +static char_u *skip_var_list __ARGS((char_u *arg, int *var_count, int *semicolon)); +static char_u *skip_var_one __ARGS((char_u *arg)); +static void list_hashtable_vars __ARGS((hashtab_T *ht, char_u *prefix, int empty)); +static void list_glob_vars __ARGS((void)); +static void list_buf_vars __ARGS((void)); +static void list_win_vars __ARGS((void)); +static void list_vim_vars __ARGS((void)); +static char_u *list_arg_vars __ARGS((exarg_T *eap, char_u *arg)); +static char_u *ex_let_one __ARGS((char_u *arg, typval_T *tv, int copy, char_u *endchars, char_u *op)); +static int check_changedtick __ARGS((char_u *arg)); +static char_u *get_lval __ARGS((char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int quiet)); +static void clear_lval __ARGS((lval_T *lp)); +static void set_var_lval __ARGS((lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op)); +static int tv_op __ARGS((typval_T *tv1, typval_T *tv2, char_u *op)); +static void list_add_watch __ARGS((list_T *l, listwatch_T *lw)); +static void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem)); +static void list_fix_watch __ARGS((list_T *l, listitem_T *item)); +static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); /* - * Initialize the global variables. + * Initialize the global and v: variables. */ void eval_init() { - hash_init(&variables); + int i; + struct vimvar *p; + + init_var_dict(&globvardict, &globvars_var); + init_var_dict(&vimvardict, &vimvars_var); + + for (i = 0; i < VV_LEN; ++i) + { + p = &vimvars[i]; + STRCPY(p->vv_di.di_key, p->vv_name); + if (p->vv_flags & VV_RO) + p->vv_di.di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; + else if (p->vv_flags & VV_RO_SBX) + p->vv_di.di_flags = DI_FLAGS_RO_SBX | DI_FLAGS_FIX; + else + p->vv_di.di_flags = DI_FLAGS_FIX; + /* add to v: scope dict */ + hash_add(&vimvarht, p->vv_di.di_key); + if (p->vv_flags & VV_COMPAT) + /* add to g: scope dict */ + hash_add(&globvardict.dv_hashtab, p->vv_di.di_key); + } } /* @@ -324,7 +625,7 @@ eval_init() func_name(cookie) void *cookie; { - return ((struct funccall *)cookie)->func->name; + return ((funccall_T *)cookie)->func->name; } /* @@ -334,7 +635,7 @@ func_name(cookie) func_breakpoint(cookie) void *cookie; { - return &((struct funccall *)cookie)->breakpoint; + return &((funccall_T *)cookie)->breakpoint; } /* @@ -344,7 +645,7 @@ func_breakpoint(cookie) func_dbg_tick(cookie) void *cookie; { - return &((struct funccall *)cookie)->dbg_tick; + return &((funccall_T *)cookie)->dbg_tick; } /* @@ -354,11 +655,11 @@ func_dbg_tick(cookie) func_level(cookie) void *cookie; { - return ((struct funccall *)cookie)->level; + return ((funccall_T *)cookie)->level; } /* pointer to funccal for currently active function */ -struct funccall *current_funccal = NULL; +funccall_T *current_funccal = NULL; /* * Return TRUE when a function was ended by a ":return" command. @@ -371,361 +672,6 @@ current_func_returned() /* - * Array to hold the value of v: variables. - */ -#include "version.h" - -/* values for flags: */ -#define VV_COMPAT 1 /* compatible, also used without "v:" */ -#define VV_RO 2 /* read-only */ -#define VV_RO_SBX 4 /* read-only in the sandbox*/ - -#define VV_NAME(s) s, sizeof(s) - 1 - -struct vimvar -{ - char *name; /* name of variable, without v: */ - int len; /* length of name */ - typeval tv; /* type and value */ - char flags; /* VV_COMPAT, VV_RO, VV_RO_SBX */ -} vimvars[VV_LEN] = -{ - /* - * The order here must match the VV_ defines in vim.h! - * Initializing a union does not work, leave tv.vval empty to get zero's. - */ - {VV_NAME("count"), {VAR_NUMBER}, VV_COMPAT+VV_RO}, - {VV_NAME("count1"), {VAR_NUMBER}, VV_RO}, - {VV_NAME("prevcount"), {VAR_NUMBER}, VV_RO}, - {VV_NAME("errmsg"), {VAR_STRING}, VV_COMPAT}, - {VV_NAME("warningmsg"), {VAR_STRING}, 0}, - {VV_NAME("statusmsg"), {VAR_STRING}, 0}, - {VV_NAME("shell_error"), {VAR_NUMBER}, VV_COMPAT+VV_RO}, - {VV_NAME("this_session"), {VAR_STRING}, VV_COMPAT}, - {VV_NAME("version"), {VAR_NUMBER}, VV_COMPAT+VV_RO}, - {VV_NAME("lnum"), {VAR_NUMBER}, VV_RO_SBX}, - {VV_NAME("termresponse"), {VAR_STRING}, VV_RO}, - {VV_NAME("fname"), {VAR_STRING}, VV_RO}, - {VV_NAME("lang"), {VAR_STRING}, VV_RO}, - {VV_NAME("lc_time"), {VAR_STRING}, VV_RO}, - {VV_NAME("ctype"), {VAR_STRING}, VV_RO}, - {VV_NAME("charconvert_from"), {VAR_STRING}, VV_RO}, - {VV_NAME("charconvert_to"), {VAR_STRING}, VV_RO}, - {VV_NAME("fname_in"), {VAR_STRING}, VV_RO}, - {VV_NAME("fname_out"), {VAR_STRING}, VV_RO}, - {VV_NAME("fname_new"), {VAR_STRING}, VV_RO}, - {VV_NAME("fname_diff"), {VAR_STRING}, VV_RO}, - {VV_NAME("cmdarg"), {VAR_STRING}, VV_RO}, - {VV_NAME("foldstart"), {VAR_NUMBER}, VV_RO_SBX}, - {VV_NAME("foldend"), {VAR_NUMBER}, VV_RO_SBX}, - {VV_NAME("folddashes"), {VAR_STRING}, VV_RO_SBX}, - {VV_NAME("foldlevel"), {VAR_NUMBER}, VV_RO_SBX}, - {VV_NAME("progname"), {VAR_STRING}, VV_RO}, - {VV_NAME("servername"), {VAR_STRING}, VV_RO}, - {VV_NAME("dying"), {VAR_NUMBER}, VV_RO}, - {VV_NAME("exception"), {VAR_STRING}, VV_RO}, - {VV_NAME("throwpoint"), {VAR_STRING}, VV_RO}, - {VV_NAME("register"), {VAR_STRING}, VV_RO}, - {VV_NAME("cmdbang"), {VAR_NUMBER}, VV_RO}, - {VV_NAME("insertmode"), {VAR_STRING}, VV_RO}, - {VV_NAME("val"), {VAR_UNKNOWN}, VV_RO}, - {VV_NAME("key"), {VAR_UNKNOWN}, VV_RO}, -}; - -/* shorthand */ -#define vv_nr tv.vval.v_number -#define vv_str tv.vval.v_string - -static int eval0 __ARGS((char_u *arg, typeval *rettv, char_u **nextcmd, int evaluate)); -static int eval1 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval2 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval3 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval4 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval5 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval6 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval7 __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int eval_index __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int get_option_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int get_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int get_lit_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); -static int get_list_tv __ARGS((char_u **arg, typeval *rettv, 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 void listitem_remove __ARGS((listvar *l, listitem *item)); -static long list_len __ARGS((listvar *l)); -static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); -static int dict_equal __ARGS((dictvar *d1, dictvar *d2, int ic)); -static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); -static int string_isa_number __ARGS((char_u *s)); -static listitem *list_find __ARGS((listvar *l, long n)); -static long list_idx_of_item __ARGS((listvar *l, listitem *item)); -static listitem *list_find_ext __ARGS((listvar *l, long *ip)); -static void list_append __ARGS((listvar *l, listitem *item)); -static int list_append_tv __ARGS((listvar *l, typeval *tv)); -static int list_insert_tv __ARGS((listvar *l, typeval *tv, listitem *item)); -static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); -static int list_concat __ARGS((listvar *l1, listvar *l2, typeval *tv)); -static listvar *list_copy __ARGS((listvar *orig, int deep)); -static void list_remove __ARGS((listvar *l, listitem *item, listitem *item2)); -static char_u *list2string __ARGS((typeval *tv)); -static void list_join __ARGS((garray_T *gap, listvar *l, char_u *sep, int echo)); - -static dictvar *dict_alloc __ARGS((void)); -static void dict_unref __ARGS((dictvar *d)); -static void dict_free __ARGS((dictvar *d)); -static dictitem *dictitem_alloc __ARGS((char_u *key)); -static dictitem *dictitem_copy __ARGS((dictitem *org)); -static void dictitem_remove __ARGS((dictvar *dict, di |