patch 9.1.0870: too many strlen() calls in eval.c

Problem:  too many strlen() calls in eval.c
Solution: Refactor eval.c to remove calls to STRLEN()
          (John Marriott)

closes: #16066

Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
John Marriott
2024-11-18 20:25:21 +01:00
committed by Christian Brabandt
parent ba9e1570d2
commit bd4614f43d
5 changed files with 66 additions and 39 deletions

View File

@ -375,14 +375,12 @@ eval_expr_typval(
{
if (expr->v_type == VAR_PARTIAL)
return eval_expr_partial(expr, argv, argc, fc_arg, rettv);
else if (expr->v_type == VAR_INSTR)
if (expr->v_type == VAR_INSTR)
return exe_typval_instr(expr, rettv);
else if (expr->v_type == VAR_FUNC || want_func)
if (expr->v_type == VAR_FUNC || want_func)
return eval_expr_func(expr, argv, argc, rettv);
else
return eval_expr_string(expr, rettv);
return OK;
return eval_expr_string(expr, rettv);
}
/*
@ -2248,7 +2246,7 @@ set_var_lval(
// handle +=, -=, *=, /=, %= and .=
di = NULL;
if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
if (eval_variable(lp->ll_name, (int)(lp->ll_name_end - lp->ll_name),
lp->ll_sid, &tv, &di, EVAL_VAR_VERBOSE) == OK)
{
if (di != NULL && check_typval_is_value(&di->di_tv) == FAIL)
@ -6153,18 +6151,33 @@ jobchan_tv2string(
class_tv2string(typval_T *tv, char_u **tofree)
{
char_u *r = NULL;
size_t rsize;
class_T *cl = tv->vval.v_class;
char_u *class_name = (char_u *)"[unknown]";
size_t class_namelen = 9;
char *s = "class";
size_t slen = 5;
if (cl != NULL && IS_INTERFACE(cl))
s = "interface";
else if (cl != NULL && IS_ENUM(cl))
s = "enum";
size_t len = STRLEN(s) + 1 +
(cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
r = *tofree = alloc(len);
vim_snprintf((char *)r, len, "%s %s", s,
cl == NULL ? "[unknown]" : (char *)cl->class_name);
if (cl != NULL)
{
class_name = cl->class_name;
class_namelen = STRLEN(cl->class_name);
if (IS_INTERFACE(cl))
{
s = "interface";
slen = 9;
}
else if (IS_ENUM(cl))
{
s = "enum";
slen = 4;
}
}
rsize = slen + 1 + class_namelen + 1;
r = *tofree = alloc(rsize);
if (r != NULL)
vim_snprintf((char *)r, rsize, "%s %s", s, (char *)class_name);
return r;
}
@ -6197,7 +6210,7 @@ object_tv2string(
else if (copyID != 0 && obj->obj_copyID == copyID
&& obj->obj_class->class_obj_member_count != 0)
{
size_t n = 25 + strlen((char *)obj->obj_class->class_name);
size_t n = 25 + STRLEN((char *)obj->obj_class->class_name);
r = alloc(n);
if (r != NULL)
(void)vim_snprintf((char *)r, n, "object of %s {...}",
@ -6911,14 +6924,14 @@ make_expanded_name(
temp_result = eval_to_string(expr_start + 1, FALSE, FALSE);
if (temp_result != NULL)
{
retval = alloc(STRLEN(temp_result) + (expr_start - in_start)
+ (in_end - expr_end) + 1);
size_t retvalsize = (size_t)(expr_start - in_start)
+ STRLEN(temp_result)
+ (size_t)(in_end - expr_end) + 1;
retval = alloc(retvalsize);
if (retval != NULL)
{
STRCPY(retval, in_start);
STRCAT(retval, temp_result);
STRCAT(retval, expr_end + 1);
}
vim_snprintf((char *)retval, retvalsize, "%s%s%s",
in_start, temp_result, expr_end + 1);
}
vim_free(temp_result);
@ -7610,21 +7623,17 @@ last_set_msg(sctx_T script_ctx)
char_u *
do_string_sub(
char_u *str,
size_t len,
char_u *pat,
char_u *sub,
typval_T *expr,
char_u *flags)
char_u *flags,
size_t *ret_len) // length of returned buffer
{
int sublen;
regmatch_T regmatch;
int i;
int do_all;
char_u *tail;
char_u *end;
garray_T ga;
char_u *ret;
char_u *save_cpo;
char_u *zero_width = NULL;
// Make 'cpoptions' empty, so that the 'l' flag doesn't work here
save_cpo = p_cpo;
@ -7632,14 +7641,17 @@ do_string_sub(
ga_init2(&ga, 1, 200);
do_all = (flags[0] == 'g');
regmatch.rm_ic = p_ic;
regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
if (regmatch.regprog != NULL)
{
tail = str;
end = str + STRLEN(str);
char_u *tail = str;
char_u *end = str + len;
int do_all = (flags[0] == 'g');
int sublen;
int i;
char_u *zero_width = NULL;
while (vim_regexec_nl(&regmatch, str, (colnr_T)(tail - str)))
{
// Skip empty match except for first match.
@ -7694,12 +7706,20 @@ do_string_sub(
}
if (ga.ga_data != NULL)
{
STRCPY((char *)ga.ga_data + ga.ga_len, tail);
ga.ga_len += (int)(end - tail);
}
vim_regfree(regmatch.regprog);
}
ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data);
if (ga.ga_data != NULL)
{
str = (char_u *)ga.ga_data;
len = (size_t)ga.ga_len;
}
ret = vim_strnsave(str, len);
ga_clear(&ga);
if (p_cpo == empty_option)
p_cpo = save_cpo;
@ -7713,5 +7733,8 @@ do_string_sub(
free_string_option(save_cpo);
}
if (ret_len != NULL)
*ret_len = len;
return ret;
}

View File

@ -11489,7 +11489,7 @@ f_substitute(typval_T *argvars, typval_T *rettv)
|| flg == NULL)
rettv->vval.v_string = NULL;
else
rettv->vval.v_string = do_string_sub(str, pat, sub, expr, flg);
rettv->vval.v_string = do_string_sub(str, STRLEN(str), pat, sub, expr, flg, NULL);
}
/*

View File

@ -668,12 +668,14 @@ repeat:
str = vim_strnsave(*fnamep, *fnamelen);
if (sub != NULL && str != NULL)
{
size_t slen;
*usedlen = p + 1 - src;
s = do_string_sub(str, pat, sub, NULL, flags);
s = do_string_sub(str, *fnamelen, pat, sub, NULL, flags, &slen);
if (s != NULL)
{
*fnamep = s;
*fnamelen = (int)STRLEN(s);
*fnamelen = slen;
vim_free(*bufp);
*bufp = s;
didit = TRUE;

View File

@ -73,5 +73,5 @@ int get_echo_attr(void);
void ex_execute(exarg_T *eap);
char_u *find_option_end(char_u **arg, int *scope);
void last_set_msg(sctx_T script_ctx);
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, typval_T *expr, char_u *flags);
char_u *do_string_sub(char_u *str, size_t str_len, char_u *pat, char_u *sub, typval_T *expr, char_u *flags, size_t *ret_len);
/* vim: set ft=c : */

View File

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