Mercurial > vim
comparison src/eval.c @ 4287:dc3efb6d5a08 v7.3.893
updated for version 7.3.893
Problem: Crash when using b:, w: or t: after closing the buffer, window or
tabpage.
Solution: Allocate the dictionary instead of having it part of the
buffer/window/tabpage struct. (Yukihiro Nakadaira)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Mon, 15 Apr 2013 12:27:36 +0200 |
parents | 23ce9a61bdc2 |
children | 11007e80829c |
comparison
equal
deleted
inserted
replaced
4286:afcc61d24129 | 4287:dc3efb6d5a08 |
---|---|
2129 list_buf_vars(first) | 2129 list_buf_vars(first) |
2130 int *first; | 2130 int *first; |
2131 { | 2131 { |
2132 char_u numbuf[NUMBUFLEN]; | 2132 char_u numbuf[NUMBUFLEN]; |
2133 | 2133 |
2134 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", | 2134 list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:", |
2135 TRUE, first); | 2135 TRUE, first); |
2136 | 2136 |
2137 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); | 2137 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); |
2138 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, | 2138 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, |
2139 numbuf, first); | 2139 numbuf, first); |
2144 */ | 2144 */ |
2145 static void | 2145 static void |
2146 list_win_vars(first) | 2146 list_win_vars(first) |
2147 int *first; | 2147 int *first; |
2148 { | 2148 { |
2149 list_hashtable_vars(&curwin->w_vars.dv_hashtab, | 2149 list_hashtable_vars(&curwin->w_vars->dv_hashtab, |
2150 (char_u *)"w:", TRUE, first); | 2150 (char_u *)"w:", TRUE, first); |
2151 } | 2151 } |
2152 | 2152 |
2153 #ifdef FEAT_WINDOWS | 2153 #ifdef FEAT_WINDOWS |
2154 /* | 2154 /* |
2156 */ | 2156 */ |
2157 static void | 2157 static void |
2158 list_tab_vars(first) | 2158 list_tab_vars(first) |
2159 int *first; | 2159 int *first; |
2160 { | 2160 { |
2161 list_hashtable_vars(&curtab->tp_vars.dv_hashtab, | 2161 list_hashtable_vars(&curtab->tp_vars->dv_hashtab, |
2162 (char_u *)"t:", TRUE, first); | 2162 (char_u *)"t:", TRUE, first); |
2163 } | 2163 } |
2164 #endif | 2164 #endif |
2165 | 2165 |
2166 /* | 2166 /* |
3946 return cat_prefix_varname('g', hi->hi_key); | 3946 return cat_prefix_varname('g', hi->hi_key); |
3947 return hi->hi_key; | 3947 return hi->hi_key; |
3948 } | 3948 } |
3949 | 3949 |
3950 /* b: variables */ | 3950 /* b: variables */ |
3951 ht = &curbuf->b_vars.dv_hashtab; | 3951 ht = &curbuf->b_vars->dv_hashtab; |
3952 if (bdone < ht->ht_used) | 3952 if (bdone < ht->ht_used) |
3953 { | 3953 { |
3954 if (bdone++ == 0) | 3954 if (bdone++ == 0) |
3955 hi = ht->ht_array; | 3955 hi = ht->ht_array; |
3956 else | 3956 else |
3964 ++bdone; | 3964 ++bdone; |
3965 return (char_u *)"b:changedtick"; | 3965 return (char_u *)"b:changedtick"; |
3966 } | 3966 } |
3967 | 3967 |
3968 /* w: variables */ | 3968 /* w: variables */ |
3969 ht = &curwin->w_vars.dv_hashtab; | 3969 ht = &curwin->w_vars->dv_hashtab; |
3970 if (wdone < ht->ht_used) | 3970 if (wdone < ht->ht_used) |
3971 { | 3971 { |
3972 if (wdone++ == 0) | 3972 if (wdone++ == 0) |
3973 hi = ht->ht_array; | 3973 hi = ht->ht_array; |
3974 else | 3974 else |
3978 return cat_prefix_varname('w', hi->hi_key); | 3978 return cat_prefix_varname('w', hi->hi_key); |
3979 } | 3979 } |
3980 | 3980 |
3981 #ifdef FEAT_WINDOWS | 3981 #ifdef FEAT_WINDOWS |
3982 /* t: variables */ | 3982 /* t: variables */ |
3983 ht = &curtab->tp_vars.dv_hashtab; | 3983 ht = &curtab->tp_vars->dv_hashtab; |
3984 if (tdone < ht->ht_used) | 3984 if (tdone < ht->ht_used) |
3985 { | 3985 { |
3986 if (tdone++ == 0) | 3986 if (tdone++ == 0) |
3987 hi = ht->ht_array; | 3987 hi = ht->ht_array; |
3988 else | 3988 else |
6785 for (i = 1; i <= ga_scripts.ga_len; ++i) | 6785 for (i = 1; i <= ga_scripts.ga_len; ++i) |
6786 set_ref_in_ht(&SCRIPT_VARS(i), copyID); | 6786 set_ref_in_ht(&SCRIPT_VARS(i), copyID); |
6787 | 6787 |
6788 /* buffer-local variables */ | 6788 /* buffer-local variables */ |
6789 for (buf = firstbuf; buf != NULL; buf = buf->b_next) | 6789 for (buf = firstbuf; buf != NULL; buf = buf->b_next) |
6790 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); | 6790 set_ref_in_item(&buf->b_bufvar.di_tv, copyID); |
6791 | 6791 |
6792 /* window-local variables */ | 6792 /* window-local variables */ |
6793 FOR_ALL_TAB_WINDOWS(tp, wp) | 6793 FOR_ALL_TAB_WINDOWS(tp, wp) |
6794 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); | 6794 set_ref_in_item(&wp->w_winvar.di_tv, copyID); |
6795 | 6795 |
6796 #ifdef FEAT_WINDOWS | 6796 #ifdef FEAT_WINDOWS |
6797 /* tabpage-local variables */ | 6797 /* tabpage-local variables */ |
6798 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) | 6798 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next) |
6799 set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID); | 6799 set_ref_in_item(&tp->tp_winvar.di_tv, copyID); |
6800 #endif | 6800 #endif |
6801 | 6801 |
6802 /* global variables */ | 6802 /* global variables */ |
6803 set_ref_in_ht(&globvarht, copyID); | 6803 set_ref_in_ht(&globvarht, copyID); |
6804 | 6804 |
11154 /* let getbufvar({nr}, "") return the "b:" dictionary. The | 11154 /* let getbufvar({nr}, "") return the "b:" dictionary. The |
11155 * scope prefix before the NUL byte is required by | 11155 * scope prefix before the NUL byte is required by |
11156 * find_var_in_ht(). */ | 11156 * find_var_in_ht(). */ |
11157 varname = (char_u *)"b:" + 2; | 11157 varname = (char_u *)"b:" + 2; |
11158 /* look up the variable */ | 11158 /* look up the variable */ |
11159 v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE); | 11159 v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, varname, FALSE); |
11160 if (v != NULL) | 11160 if (v != NULL) |
11161 copy_tv(&v->di_tv, rettv); | 11161 copy_tv(&v->di_tv, rettv); |
11162 } | 11162 } |
11163 | 11163 |
11164 /* restore previous notion of curbuf */ | 11164 /* restore previous notion of curbuf */ |
11777 varname = get_tv_string_chk(&argvars[1]); | 11777 varname = get_tv_string_chk(&argvars[1]); |
11778 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); | 11778 tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); |
11779 if (tp != NULL && varname != NULL) | 11779 if (tp != NULL && varname != NULL) |
11780 { | 11780 { |
11781 /* look up the variable */ | 11781 /* look up the variable */ |
11782 v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE); | 11782 v = find_var_in_ht(&tp->tp_vars->dv_hashtab, varname, FALSE); |
11783 if (v != NULL) | 11783 if (v != NULL) |
11784 copy_tv(&v->di_tv, rettv); | 11784 copy_tv(&v->di_tv, rettv); |
11785 else if (argvars[2].v_type != VAR_UNKNOWN) | 11785 else if (argvars[2].v_type != VAR_UNKNOWN) |
11786 copy_tv(&argvars[2], rettv); | 11786 copy_tv(&argvars[2], rettv); |
11787 } | 11787 } |
11933 /* let getwinvar({nr}, "") return the "w:" dictionary. The | 11933 /* let getwinvar({nr}, "") return the "w:" dictionary. The |
11934 * scope prefix before the NUL byte is required by | 11934 * scope prefix before the NUL byte is required by |
11935 * find_var_in_ht(). */ | 11935 * find_var_in_ht(). */ |
11936 varname = (char_u *)"w:" + 2; | 11936 varname = (char_u *)"w:" + 2; |
11937 /* look up the variable */ | 11937 /* look up the variable */ |
11938 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); | 11938 v = find_var_in_ht(&win->w_vars->dv_hashtab, varname, FALSE); |
11939 if (v != NULL) | 11939 if (v != NULL) |
11940 copy_tv(&v->di_tv, rettv); | 11940 copy_tv(&v->di_tv, rettv); |
11941 } | 11941 } |
11942 | 11942 |
11943 /* restore previous notion of curwin */ | 11943 /* restore previous notion of curwin */ |
14331 | 14331 |
14332 rettv->vval.v_string = vim_strsave(buf); | 14332 rettv->vval.v_string = vim_strsave(buf); |
14333 rettv->v_type = VAR_STRING; | 14333 rettv->v_type = VAR_STRING; |
14334 } | 14334 } |
14335 | 14335 |
14336 #ifdef FEAT_MZSCHEME | 14336 #if defined(FEAT_MZSCHEME) || defined(PROTO) |
14337 /* | 14337 /* |
14338 * "mzeval()" function | 14338 * "mzeval()" function |
14339 */ | 14339 */ |
14340 static void | 14340 static void |
14341 f_mzeval(argvars, rettv) | 14341 f_mzeval(argvars, rettv) |
20132 */ | 20132 */ |
20133 if (vim_strchr(name + 2, ':') != NULL | 20133 if (vim_strchr(name + 2, ':') != NULL |
20134 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) | 20134 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) |
20135 return NULL; | 20135 return NULL; |
20136 if (*name == 'b') /* buffer variable */ | 20136 if (*name == 'b') /* buffer variable */ |
20137 return &curbuf->b_vars.dv_hashtab; | 20137 return &curbuf->b_vars->dv_hashtab; |
20138 if (*name == 'w') /* window variable */ | 20138 if (*name == 'w') /* window variable */ |
20139 return &curwin->w_vars.dv_hashtab; | 20139 return &curwin->w_vars->dv_hashtab; |
20140 #ifdef FEAT_WINDOWS | 20140 #ifdef FEAT_WINDOWS |
20141 if (*name == 't') /* tab page variable */ | 20141 if (*name == 't') /* tab page variable */ |
20142 return &curtab->tp_vars.dv_hashtab; | 20142 return &curtab->tp_vars->dv_hashtab; |
20143 #endif | 20143 #endif |
20144 if (*name == 'v') /* v: variable */ | 20144 if (*name == 'v') /* v: variable */ |
20145 return &vimvarht; | 20145 return &vimvarht; |
20146 if (*name == 'a' && current_funccal != NULL) /* function argument */ | 20146 if (*name == 'a' && current_funccal != NULL) /* function argument */ |
20147 return ¤t_funccal->l_avars.dv_hashtab; | 20147 return ¤t_funccal->l_avars.dv_hashtab; |
20224 dict_var->di_tv.vval.v_dict = dict; | 20224 dict_var->di_tv.vval.v_dict = dict; |
20225 dict_var->di_tv.v_type = VAR_DICT; | 20225 dict_var->di_tv.v_type = VAR_DICT; |
20226 dict_var->di_tv.v_lock = VAR_FIXED; | 20226 dict_var->di_tv.v_lock = VAR_FIXED; |
20227 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; | 20227 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; |
20228 dict_var->di_key[0] = NUL; | 20228 dict_var->di_key[0] = NUL; |
20229 } | |
20230 | |
20231 /* | |
20232 * Unreference a dictionary initialized by init_var_dict(). | |
20233 */ | |
20234 void | |
20235 unref_var_dict(dict) | |
20236 dict_T *dict; | |
20237 { | |
20238 /* Now the dict needs to be freed if no one else is using it, go back to | |
20239 * normal reference counting. */ | |
20240 dict->dv_refcount -= DO_NOT_FREE_CNT - 1; | |
20241 dict_unref(dict); | |
20229 } | 20242 } |
20230 | 20243 |
20231 /* | 20244 /* |
20232 * Clean up a list of internal variables. | 20245 * Clean up a list of internal variables. |
20233 * Frees all allocated variables and the value they contain. | 20246 * Frees all allocated variables and the value they contain. |