diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 106 |
1 files changed, 69 insertions, 37 deletions
diff --git a/src/eval.c b/src/eval.c index c30c5d83c0..484f9bcc45 100644 --- a/src/eval.c +++ b/src/eval.c @@ -247,6 +247,7 @@ static typval_T *alloc_string_tv(char_u *string); static void delete_var(hashtab_T *ht, hashitem_T *hi); static void list_one_var(dictitem_T *v, char *prefix, int *first); static void list_one_var_a(char *prefix, char_u *name, int type, char_u *string, int *first); +static int tv_check_lock(typval_T *tv, char_u *name, int use_gettext); static char_u *find_option_end(char_u **arg, int *opt_flags); /* for VIM_VERSION_ defines */ @@ -2332,9 +2333,8 @@ set_var_lval( &tv, &di, TRUE, FALSE) == OK) { if ((di == NULL - || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) - && !tv_check_lock(di->di_tv.v_lock, lp->ll_name, - FALSE))) + || (!var_check_ro(di->di_flags, lp->ll_name, FALSE) + && !tv_check_lock(&di->di_tv, lp->ll_name, FALSE))) && tv_op(&tv, rettv, op) == OK) set_var(lp->ll_name, &tv, FALSE); clear_tv(&tv); @@ -2344,7 +2344,7 @@ set_var_lval( set_var(lp->ll_name, rettv, copy); *endp = cc; } - else if (tv_check_lock(lp->ll_newkey == NULL + else if (var_check_lock(lp->ll_newkey == NULL ? lp->ll_tv->v_lock : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name, FALSE)) ; @@ -2358,7 +2358,7 @@ set_var_lval( */ for (ri = rettv->vval.v_list->lv_first; ri != NULL && ll_li != NULL; ) { - if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) + if (var_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) return; ri = ri->li_next; if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == ll_n1)) @@ -2951,9 +2951,9 @@ do_unlet_var( *name_end = cc; } else if ((lp->ll_list != NULL - && tv_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) + && var_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) || (lp->ll_dict != NULL - && tv_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) + && var_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) return FAIL; else if (lp->ll_range) { @@ -2964,7 +2964,7 @@ do_unlet_var( while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) { li = ll_li->li_next; - if (tv_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) + if (var_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) return FAIL; ll_li = li; ++ll_n1; @@ -3034,7 +3034,7 @@ do_unlet(char_u *name, int forceit) di = HI2DI(hi); if (var_check_fixed(di->di_flags, name, FALSE) || var_check_ro(di->di_flags, name, FALSE) - || tv_check_lock(d->dv_lock, name, FALSE)) + || var_check_lock(d->dv_lock, name, FALSE)) return FAIL; delete_var(ht, hi); @@ -7866,7 +7866,7 @@ set_var( { /* existing variable, need to clear the value */ if (var_check_ro(v->di_flags, name, FALSE) - || tv_check_lock(v->di_tv.v_lock, name, FALSE)) + || var_check_lock(v->di_tv.v_lock, name, FALSE)) return; /* @@ -8021,31 +8021,12 @@ var_check_func_name( } /* - * Check if a variable name is valid. - * Return FALSE and give an error if not. - */ - int -valid_varname(char_u *varname) -{ - char_u *p; - - for (p = varname; *p != NUL; ++p) - if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) - && *p != AUTOLOAD_CHAR) - { - semsg(_(e_illvar), varname); - return FALSE; - } - return TRUE; -} - -/* - * Return TRUE if typeval "tv" is set to be locked (immutable). + * Return TRUE if "flags" indicates variable "name" is locked (immutable). * Also give an error message, using "name" or _("name") when use_gettext is * TRUE. */ int -tv_check_lock(int lock, char_u *name, int use_gettext) +var_check_lock(int lock, char_u *name, int use_gettext) { if (lock & VAR_LOCKED) { @@ -8067,6 +8048,56 @@ tv_check_lock(int lock, char_u *name, int use_gettext) } /* + * Return TRUE if typeval "tv" and its value are set to be locked (immutable). + * Also give an error message, using "name" or _("name") when use_gettext is + * TRUE. + */ + static int +tv_check_lock(typval_T *tv, char_u *name, int use_gettext) +{ + int lock = 0; + + switch (tv->v_type) + { + case VAR_BLOB: + if (tv->vval.v_blob != NULL) + lock = tv->vval.v_blob->bv_lock; + break; + case VAR_LIST: + if (tv->vval.v_list != NULL) + lock = tv->vval.v_list->lv_lock; + break; + case VAR_DICT: + if (tv->vval.v_dict != NULL) + lock = tv->vval.v_dict->dv_lock; + break; + default: + break; + } + return var_check_lock(tv->v_lock, name, use_gettext) + || (lock != 0 && var_check_lock(lock, name, use_gettext)); +} + +/* + * Check if a variable name is valid. + * Return FALSE and give an error if not. + */ + int +valid_varname(char_u *varname) +{ + char_u *p; + + for (p = varname; *p != NUL; ++p) + if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p)) + && *p != AUTOLOAD_CHAR) + { + semsg(_(e_illvar), varname); + return FALSE; + } + return TRUE; +} + +/* * Copy the values from typval_T "from" to typval_T "to". * When needed allocates string or increases reference count. * Does not make a copy of a list, blob or dict but copies the reference! @@ -10711,13 +10742,13 @@ filter_map(typval_T *argvars, typval_T *rettv, int map) else if (argvars[0].v_type == VAR_LIST) { if ((l = argvars[0].vval.v_list) == NULL - || (!map && tv_check_lock(l->lv_lock, arg_errmsg, TRUE))) + || (!map && var_check_lock(l->lv_lock, arg_errmsg, TRUE))) return; } else if (argvars[0].v_type == VAR_DICT) { if ((d = argvars[0].vval.v_dict) == NULL - || (!map && tv_check_lock(d->dv_lock, arg_errmsg, TRUE))) + || (!map && var_check_lock(d->dv_lock, arg_errmsg, TRUE))) return; } else @@ -10755,9 +10786,10 @@ filter_map(typval_T *argvars, typval_T *rettv, int map) --todo; di = HI2DI(hi); - if (map && - (tv_check_lock(di->di_tv.v_lock, arg_errmsg, TRUE) - || var_check_ro(di->di_flags, arg_errmsg, TRUE))) + if (map && (var_check_lock(di->di_tv.v_lock, + arg_errmsg, TRUE) + || var_check_ro(di->di_flags, + arg_errmsg, TRUE))) break; vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); r = filter_map_one(&di->di_tv, expr, map, &rem); @@ -10813,7 +10845,7 @@ filter_map(typval_T *argvars, typval_T *rettv, int map) for (li = l->lv_first; li != NULL; li = nli) { - if (map && tv_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) + if (map && var_check_lock(li->li_tv.v_lock, arg_errmsg, TRUE)) break; nli = li->li_next; vimvars[VV_KEY].vv_nr = idx; |