Mercurial > vim
comparison src/eval.c @ 3687:085f14642fe8 v7.3.603
updated for version 7.3.603
Problem: It is possible to add replace builtin functions by calling
extend() on g:.
Solution: Add a flag to a dict to indicate it is a scope. Check for
existing functions. (ZyX)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Mon, 16 Jul 2012 17:31:53 +0200 |
parents | 46896c29edd7 |
children | acd91c9741a6 |
comparison
equal
deleted
inserted
replaced
3686:612cfb8dc628 | 3687:085f14642fe8 |
---|---|
848 eval_init() | 848 eval_init() |
849 { | 849 { |
850 int i; | 850 int i; |
851 struct vimvar *p; | 851 struct vimvar *p; |
852 | 852 |
853 init_var_dict(&globvardict, &globvars_var); | 853 init_var_dict(&globvardict, &globvars_var, VAR_DEF_SCOPE); |
854 init_var_dict(&vimvardict, &vimvars_var); | 854 init_var_dict(&vimvardict, &vimvars_var, VAR_SCOPE); |
855 vimvardict.dv_lock = VAR_FIXED; | 855 vimvardict.dv_lock = VAR_FIXED; |
856 hash_init(&compat_hashtab); | 856 hash_init(&compat_hashtab); |
857 hash_init(&func_hashtab); | 857 hash_init(&func_hashtab); |
858 | 858 |
859 for (i = 0; i < VV_LEN; ++i) | 859 for (i = 0; i < VV_LEN; ++i) |
2723 } | 2723 } |
2724 lp->ll_list = NULL; | 2724 lp->ll_list = NULL; |
2725 lp->ll_dict = lp->ll_tv->vval.v_dict; | 2725 lp->ll_dict = lp->ll_tv->vval.v_dict; |
2726 lp->ll_di = dict_find(lp->ll_dict, key, len); | 2726 lp->ll_di = dict_find(lp->ll_dict, key, len); |
2727 | 2727 |
2728 /* When assigning to g: check that a function and variable name is | 2728 /* When assigning to a scope dictionary check that a function and |
2729 * valid. */ | 2729 * variable name is valid (only variable name unless it is l: or |
2730 if (rettv != NULL && lp->ll_dict == &globvardict) | 2730 * g: dictionary). Disallow overwriting a builtin function. */ |
2731 if (rettv != NULL && lp->ll_dict->dv_scope != 0) | |
2731 { | 2732 { |
2732 if (rettv->v_type == VAR_FUNC | 2733 int prevval; |
2734 int wrong; | |
2735 | |
2736 if (len != -1) | |
2737 { | |
2738 prevval = key[len]; | |
2739 key[len] = NUL; | |
2740 } | |
2741 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE | |
2742 && rettv->v_type == VAR_FUNC | |
2733 && var_check_func_name(key, lp->ll_di == NULL)) | 2743 && var_check_func_name(key, lp->ll_di == NULL)) |
2734 return NULL; | 2744 || !valid_varname(key); |
2735 if (!valid_varname(key)) | 2745 if (len != -1) |
2746 key[len] = prevval; | |
2747 if (wrong) | |
2736 return NULL; | 2748 return NULL; |
2737 } | 2749 } |
2738 | 2750 |
2739 if (lp->ll_di == NULL) | 2751 if (lp->ll_di == NULL) |
2740 { | 2752 { |
6949 dict_T *d; | 6961 dict_T *d; |
6950 | 6962 |
6951 d = (dict_T *)alloc(sizeof(dict_T)); | 6963 d = (dict_T *)alloc(sizeof(dict_T)); |
6952 if (d != NULL) | 6964 if (d != NULL) |
6953 { | 6965 { |
6954 /* Add the list to the list of dicts for garbage collection. */ | 6966 /* Add the dict to the list of dicts for garbage collection. */ |
6955 if (first_dict != NULL) | 6967 if (first_dict != NULL) |
6956 first_dict->dv_used_prev = d; | 6968 first_dict->dv_used_prev = d; |
6957 d->dv_used_next = first_dict; | 6969 d->dv_used_next = first_dict; |
6958 d->dv_used_prev = NULL; | 6970 d->dv_used_prev = NULL; |
6959 first_dict = d; | 6971 first_dict = d; |
6960 | 6972 |
6961 hash_init(&d->dv_hashtab); | 6973 hash_init(&d->dv_hashtab); |
6962 d->dv_lock = 0; | 6974 d->dv_lock = 0; |
6975 d->dv_scope = 0; | |
6963 d->dv_refcount = 0; | 6976 d->dv_refcount = 0; |
6964 d->dv_copyID = 0; | 6977 d->dv_copyID = 0; |
6965 } | 6978 } |
6966 return d; | 6979 return d; |
6967 } | 6980 } |
10201 { | 10214 { |
10202 if (!HASHITEM_EMPTY(hi2)) | 10215 if (!HASHITEM_EMPTY(hi2)) |
10203 { | 10216 { |
10204 --todo; | 10217 --todo; |
10205 di1 = dict_find(d1, hi2->hi_key, -1); | 10218 di1 = dict_find(d1, hi2->hi_key, -1); |
10219 if (d1->dv_scope != 0) | |
10220 { | |
10221 /* Disallow replacing a builtin function in l: and g:. | |
10222 * Check the key to be valid when adding to any | |
10223 * scope. */ | |
10224 if (d1->dv_scope == VAR_DEF_SCOPE | |
10225 && HI2DI(hi2)->di_tv.v_type == VAR_FUNC | |
10226 && var_check_func_name(hi2->hi_key, | |
10227 di1 == NULL)) | |
10228 break; | |
10229 if (!valid_varname(hi2->hi_key)) | |
10230 break; | |
10231 } | |
10206 if (di1 == NULL) | 10232 if (di1 == NULL) |
10207 { | 10233 { |
10208 di1 = dictitem_copy(HI2DI(hi2)); | 10234 di1 = dictitem_copy(HI2DI(hi2)); |
10209 if (di1 != NULL && dict_add(d1, di1) == FAIL) | 10235 if (di1 != NULL && dict_add(d1, di1) == FAIL) |
10210 dictitem_free(di1); | 10236 dictitem_free(di1); |
20025 | 20051 |
20026 while (ga_scripts.ga_len < id) | 20052 while (ga_scripts.ga_len < id) |
20027 { | 20053 { |
20028 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = | 20054 sv = SCRIPT_SV(ga_scripts.ga_len + 1) = |
20029 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); | 20055 (scriptvar_T *)alloc_clear(sizeof(scriptvar_T)); |
20030 init_var_dict(&sv->sv_dict, &sv->sv_var); | 20056 init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE); |
20031 ++ga_scripts.ga_len; | 20057 ++ga_scripts.ga_len; |
20032 } | 20058 } |
20033 } | 20059 } |
20034 } | 20060 } |
20035 | 20061 |
20036 /* | 20062 /* |
20037 * Initialize dictionary "dict" as a scope and set variable "dict_var" to | 20063 * Initialize dictionary "dict" as a scope and set variable "dict_var" to |
20038 * point to it. | 20064 * point to it. |
20039 */ | 20065 */ |
20040 void | 20066 void |
20041 init_var_dict(dict, dict_var) | 20067 init_var_dict(dict, dict_var, scope) |
20042 dict_T *dict; | 20068 dict_T *dict; |
20043 dictitem_T *dict_var; | 20069 dictitem_T *dict_var; |
20070 int scope; | |
20044 { | 20071 { |
20045 hash_init(&dict->dv_hashtab); | 20072 hash_init(&dict->dv_hashtab); |
20046 dict->dv_lock = 0; | 20073 dict->dv_lock = 0; |
20074 dict->dv_scope = scope; | |
20047 dict->dv_refcount = DO_NOT_FREE_CNT; | 20075 dict->dv_refcount = DO_NOT_FREE_CNT; |
20048 dict->dv_copyID = 0; | 20076 dict->dv_copyID = 0; |
20049 dict_var->di_tv.vval.v_dict = dict; | 20077 dict_var->di_tv.vval.v_dict = dict; |
20050 dict_var->di_tv.v_type = VAR_DICT; | 20078 dict_var->di_tv.v_type = VAR_DICT; |
20051 dict_var->di_tv.v_lock = VAR_FIXED; | 20079 dict_var->di_tv.v_lock = VAR_FIXED; |
22302 * each argument variable and saves a lot of time. | 22330 * each argument variable and saves a lot of time. |
22303 */ | 22331 */ |
22304 /* | 22332 /* |
22305 * Init l: variables. | 22333 * Init l: variables. |
22306 */ | 22334 */ |
22307 init_var_dict(&fc->l_vars, &fc->l_vars_var); | 22335 init_var_dict(&fc->l_vars, &fc->l_vars_var, VAR_DEF_SCOPE); |
22308 if (selfdict != NULL) | 22336 if (selfdict != NULL) |
22309 { | 22337 { |
22310 /* Set l:self to "selfdict". Use "name" to avoid a warning from | 22338 /* Set l:self to "selfdict". Use "name" to avoid a warning from |
22311 * some compiler that checks the destination size. */ | 22339 * some compiler that checks the destination size. */ |
22312 v = &fc->fixvar[fixvar_idx++].var; | 22340 v = &fc->fixvar[fixvar_idx++].var; |
22323 /* | 22351 /* |
22324 * Init a: variables. | 22352 * Init a: variables. |
22325 * Set a:0 to "argcount". | 22353 * Set a:0 to "argcount". |
22326 * Set a:000 to a list with room for the "..." arguments. | 22354 * Set a:000 to a list with room for the "..." arguments. |
22327 */ | 22355 */ |
22328 init_var_dict(&fc->l_avars, &fc->l_avars_var); | 22356 init_var_dict(&fc->l_avars, &fc->l_avars_var, VAR_SCOPE); |
22329 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", | 22357 add_nr_var(&fc->l_avars, &fc->fixvar[fixvar_idx++].var, "0", |
22330 (varnumber_T)(argcount - fp->uf_args.ga_len)); | 22358 (varnumber_T)(argcount - fp->uf_args.ga_len)); |
22331 /* Use "name" to avoid a warning from some compiler that checks the | 22359 /* Use "name" to avoid a warning from some compiler that checks the |
22332 * destination size. */ | 22360 * destination size. */ |
22333 v = &fc->fixvar[fixvar_idx++].var; | 22361 v = &fc->fixvar[fixvar_idx++].var; |