0
0
mirror of https://github.com/vim/vim.git synced 2025-09-29 04:34:16 -04:00

patch 8.2.3689: ex_let_one() is too long

Problem:    ex_let_one() is too long.
Solution:   Split into multiple functions.
This commit is contained in:
Bram Moolenaar
2021-11-28 19:53:42 +00:00
parent 2e0f3ecb70
commit 3ccb579516
2 changed files with 251 additions and 195 deletions

View File

@@ -1289,39 +1289,20 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
} }
/* /*
* Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. * Set an environment variable, part of ex_let_one().
* Returns a pointer to the char just after the var name.
* Returns NULL if there is an error.
*/ */
static char_u * static char_u *
ex_let_one( ex_let_env(
char_u *arg, // points to variable name char_u *arg,
typval_T *tv, // value to assign to variable typval_T *tv,
int copy, // copy value from "tv" int flags,
int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc. char_u *endchars,
char_u *endchars, // valid chars after variable name or NULL char_u *op)
char_u *op, // "+", "-", "." or NULL
int var_idx) // variable index for "let [a, b] = list"
{ {
int c1;
char_u *name;
char_u *p;
char_u *arg_end = NULL; char_u *arg_end = NULL;
char_u *name;
int len; int len;
int opt_flags;
char_u *tofree = NULL;
if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
{
vim9_declare_error(arg);
return NULL;
}
// ":let $VAR = expr": Set environment variable.
if (*arg == '$')
{
if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
&& (flags & ASSIGN_FOR_LOOP) == 0) && (flags & ASSIGN_FOR_LOOP) == 0)
{ {
@@ -1344,7 +1325,10 @@ ex_let_one(
emsg(_(e_unexpected_characters_in_let)); emsg(_(e_unexpected_characters_in_let));
else if (!check_secure()) else if (!check_secure())
{ {
c1 = name[len]; char_u *tofree = NULL;
int c1 = name[len];
char_u *p;
name[len] = NUL; name[len] = NUL;
p = tv_get_string_chk(tv); p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') if (p != NULL && op != NULL && *op == '.')
@@ -1368,20 +1352,31 @@ ex_let_one(
vim_free(tofree); vim_free(tofree);
} }
} }
} return arg_end;
}
/*
* Set an option, part of ex_let_one().
*/
static char_u *
ex_let_option(
char_u *arg,
typval_T *tv,
int flags,
char_u *endchars,
char_u *op)
{
char_u *p;
int opt_flags;
char_u *arg_end = NULL;
// ":let &option = expr": Set option value.
// ":let &l:option = expr": Set local option value.
// ":let &g:option = expr": Set global option value.
// ":for &ts in range(8)": Set option value for for loop
else if (*arg == '&')
{
if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
&& (flags & ASSIGN_FOR_LOOP) == 0) && (flags & ASSIGN_FOR_LOOP) == 0)
{ {
emsg(_(e_const_option)); emsg(_(e_const_option));
return NULL; return NULL;
} }
// Find the end of the name. // Find the end of the name.
p = find_option_end(&arg, &opt_flags); p = find_option_end(&arg, &opt_flags);
if (p == NULL || (endchars != NULL if (p == NULL || (endchars != NULL
@@ -1389,6 +1384,7 @@ ex_let_one(
emsg(_(e_unexpected_characters_in_let)); emsg(_(e_unexpected_characters_in_let));
else else
{ {
int c1;
long n = 0; long n = 0;
getoption_T opt_type; getoption_T opt_type;
long numval; long numval;
@@ -1422,8 +1418,7 @@ ex_let_one(
if (op != NULL && *op != '=') if (op != NULL && *op != '=')
{ {
if (((opt_type == gov_bool || opt_type == gov_number) if (((opt_type == gov_bool || opt_type == gov_number) && *op == '.')
&& *op == '.')
|| (opt_type == gov_string && *op != '.')) || (opt_type == gov_string && *op != '.'))
{ {
semsg(_(e_letwrong), op); semsg(_(e_letwrong), op);
@@ -1472,11 +1467,22 @@ ex_let_one(
*p = c1; *p = c1;
vim_free(stringval); vim_free(stringval);
} }
} return arg_end;
}
/*
* Set a register, part of ex_let_one().
*/
static char_u *
ex_let_register(
char_u *arg,
typval_T *tv,
int flags,
char_u *endchars,
char_u *op)
{
char_u *arg_end = NULL;
// ":let @r = expr": Set register contents.
else if (*arg == '@')
{
if ((flags & (ASSIGN_CONST | ASSIGN_FINAL)) if ((flags & (ASSIGN_CONST | ASSIGN_FINAL))
&& (flags & ASSIGN_FOR_LOOP) == 0) && (flags & ASSIGN_FOR_LOOP) == 0)
{ {
@@ -1492,12 +1498,14 @@ ex_let_one(
else else
{ {
char_u *ptofree = NULL; char_u *ptofree = NULL;
char_u *s; char_u *p;
p = tv_get_string_chk(tv); p = tv_get_string_chk(tv);
if (p != NULL && op != NULL && *op == '.') if (p != NULL && op != NULL && *op == '.')
{ {
s = get_reg_contents(*arg == '@' ? '"' : *arg, GREG_EXPR_SRC); char_u *s = get_reg_contents(*arg == '@'
? '"' : *arg, GREG_EXPR_SRC);
if (s != NULL) if (s != NULL)
{ {
p = ptofree = concat_str(s, p); p = ptofree = concat_str(s, p);
@@ -1511,15 +1519,60 @@ ex_let_one(
} }
vim_free(ptofree); vim_free(ptofree);
} }
return arg_end;
}
/*
* Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value.
* Returns a pointer to the char just after the var name.
* Returns NULL if there is an error.
*/
static char_u *
ex_let_one(
char_u *arg, // points to variable name
typval_T *tv, // value to assign to variable
int copy, // copy value from "tv"
int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
char_u *endchars, // valid chars after variable name or NULL
char_u *op, // "+", "-", "." or NULL
int var_idx) // variable index for "let [a, b] = list"
{
char_u *arg_end = NULL;
if (in_vim9script() && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
&& (flags & (ASSIGN_CONST | ASSIGN_FINAL)) == 0
&& vim_strchr((char_u *)"$@&", *arg) != NULL)
{
vim9_declare_error(arg);
return NULL;
} }
if (*arg == '$')
{
// ":let $VAR = expr": Set environment variable.
return ex_let_env(arg, tv, flags, endchars, op);
}
else if (*arg == '&')
{
// ":let &option = expr": Set option value.
// ":let &l:option = expr": Set local option value.
// ":let &g:option = expr": Set global option value.
// ":for &ts in range(8)": Set option value for for loop
return ex_let_option(arg, tv, flags, endchars, op);
}
else if (*arg == '@')
{
// ":let @r = expr": Set register contents.
return ex_let_register(arg, tv, flags, endchars, op);
}
else if (eval_isnamec1(*arg) || *arg == '{')
{
lval_T lv;
char_u *p;
// ":let var = expr": Set internal variable. // ":let var = expr": Set internal variable.
// ":let var: type = expr": Set internal variable with type. // ":let var: type = expr": Set internal variable with type.
// ":let {expr} = expr": Idem, name made with curly braces // ":let {expr} = expr": Idem, name made with curly braces
else if (eval_isnamec1(*arg) || *arg == '{')
{
lval_T lv;
p = get_lval(arg, tv, &lv, FALSE, FALSE, p = get_lval(arg, tv, &lv, FALSE, FALSE,
(flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) (flags & (ASSIGN_NO_DECL | ASSIGN_DECL))
? GLV_NO_DECL : 0, FNE_CHECK_START); ? GLV_NO_DECL : 0, FNE_CHECK_START);
@@ -1527,7 +1580,9 @@ ex_let_one(
{ {
if (endchars != NULL && vim_strchr(endchars, if (endchars != NULL && vim_strchr(endchars,
*skipwhite(lv.ll_name_end)) == NULL) *skipwhite(lv.ll_name_end)) == NULL)
{
emsg(_(e_unexpected_characters_in_let)); emsg(_(e_unexpected_characters_in_let));
}
else else
{ {
set_var_lval(&lv, p, tv, copy, flags, op, var_idx); set_var_lval(&lv, p, tv, copy, flags, op, var_idx);
@@ -1536,7 +1591,6 @@ ex_let_one(
} }
clear_lval(&lv); clear_lval(&lv);
} }
else else
semsg(_(e_invarg2), arg); semsg(_(e_invarg2), arg);

View File

@@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3689,
/**/ /**/
3688, 3688,
/**/ /**/