Mercurial > vim
diff src/evalvars.c @ 22298:07e48ee8c3bb v8.2.1698
patch 8.2.1698: cannot lock a variable in legacy Vim script like in Vim9
Commit: https://github.com/vim/vim/commit/a187c43cfe8863d48b2159d695fedcb71f8525c1
Author: Bram Moolenaar <Bram@vim.org>
Date: Wed Sep 16 21:08:28 2020 +0200
patch 8.2.1698: cannot lock a variable in legacy Vim script like in Vim9
Problem: Cannot lock a variable in legacy Vim script like in Vim9.
Solution: Make ":lockvar 0" work.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Wed, 16 Sep 2020 21:15:05 +0200 |
parents | eb1f5f618c75 |
children | a9fb7efa31d6 |
line wrap: on
line diff
--- a/src/evalvars.c +++ b/src/evalvars.c @@ -1560,9 +1560,9 @@ do_unlet_var( *name_end = cc; } else if ((lp->ll_list != NULL - && var_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) + && value_check_lock(lp->ll_list->lv_lock, lp->ll_name, FALSE)) || (lp->ll_dict != NULL - && var_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) + && value_check_lock(lp->ll_dict->dv_lock, lp->ll_name, FALSE))) return FAIL; else if (lp->ll_range) { @@ -1573,7 +1573,7 @@ do_unlet_var( while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1)) { li = ll_li->li_next; - if (var_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) + if (value_check_lock(ll_li->li_tv.v_lock, lp->ll_name, FALSE)) return FAIL; ll_li = li; ++ll_n1; @@ -1646,7 +1646,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) - || var_check_lock(d->dv_lock, name, FALSE)) + || value_check_lock(d->dv_lock, name, FALSE)) return FAIL; delete_var(ht, hi); @@ -1677,9 +1677,6 @@ do_lock_var( int cc; dictitem_T *di; - if (deep == 0) // nothing to do - return OK; - if (lp->ll_tv == NULL) { cc = *name_end; @@ -1710,11 +1707,16 @@ do_lock_var( di->di_flags |= DI_FLAGS_LOCK; else di->di_flags &= ~DI_FLAGS_LOCK; - item_lock(&di->di_tv, deep, lock, FALSE); + if (deep != 0) + item_lock(&di->di_tv, deep, lock, FALSE); } } *name_end = cc; } + else if (deep == 0) + { + // nothing to do + } else if (lp->ll_range) { listitem_T *li = lp->ll_li; @@ -3007,8 +3009,13 @@ set_var_const( goto failed; } + // Check in this order for backwards compatibility: + // - Whether the variable is read-only + // - Whether the variable value is locked + // - Whether the variable is locked if (var_check_ro(di->di_flags, name, FALSE) - || var_check_lock(di->di_tv.v_lock, name, FALSE)) + || value_check_lock(di->di_tv.v_lock, name, FALSE) + || var_check_lock(di->di_flags, name, FALSE)) goto failed; } else @@ -3158,6 +3165,22 @@ var_check_ro(int flags, char_u *name, in } /* + * Return TRUE if di_flags "flags" indicates variable "name" is locked. + * Also give an error message. + */ + int +var_check_lock(int flags, char_u *name, int use_gettext) +{ + if (flags & DI_FLAGS_LOCK) + { + semsg(_(e_variable_is_locked_str), + use_gettext ? (char_u *)_(name) : name); + return TRUE; + } + return FALSE; +} + +/* * Return TRUE if di_flags "flags" indicates variable "name" is fixed. * Also give an error message. */ @@ -3204,12 +3227,12 @@ var_wrong_func_name( } /* - * Return TRUE if "flags" indicates variable "name" is locked (immutable). - * Also give an error message, using "name" or _("name") when use_gettext is - * TRUE. + * Return TRUE if "flags" indicates variable "name" has a locked (immutable) + * value. Also give an error message, using "name" or _("name") when + * "use_gettext" is TRUE. */ int -var_check_lock(int lock, char_u *name, int use_gettext) +value_check_lock(int lock, char_u *name, int use_gettext) { if (lock & VAR_LOCKED) {