0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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.
This commit is contained in:
Bram Moolenaar
2020-09-16 21:08:28 +02:00
parent 7707228aac
commit a187c43cfe
11 changed files with 93 additions and 44 deletions

View File

@@ -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
@@ -3157,6 +3164,22 @@ var_check_ro(int flags, char_u *name, int use_gettext)
return FALSE;
}
/*
* 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)
{