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;