summaryrefslogtreecommitdiffstats
path: root/src/evalvars.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-09-16 21:08:28 +0200
committerBram Moolenaar <Bram@vim.org>2020-09-16 21:08:28 +0200
commita187c43cfe8863d48b2159d695fedcb71f8525c1 (patch)
tree40cd63746c55f16dadb674da3d1ffab7f23f291b /src/evalvars.c
parent7707228aace9aff16434edf5377a354c6ad07316 (diff)
patch 8.2.1698: cannot lock a variable in legacy Vim script like in Vim9v8.2.1698
Problem: Cannot lock a variable in legacy Vim script like in Vim9. Solution: Make ":lockvar 0" work.
Diffstat (limited to 'src/evalvars.c')
-rw-r--r--src/evalvars.c49
1 files changed, 36 insertions, 13 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index 1c40f4111f..5ceaca48a0 100644
--- 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, int use_gettext)
}
/*
+ * 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)
{