patch 9.1.0870: too many strlen() calls in eval.c Commit: https://github.com/vim/vim/commit/bd4614f43d0eac4aff743132bab8e53b015ac801 Author: John Marriott <basil...@internode.on.net> Date: Mon Nov 18 20:25:21 2024 +0100
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 <basil...@internode.on.net> Signed-off-by: Christian Brabandt <c...@256bit.org> diff --git a/src/eval.c b/src/eval.c index cc289b453..fabe9643c 100644 --- a/src/eval.c +++ b/src/eval.c @@ -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) + { + 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; + } + } - 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); + 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(®match, 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; } diff --git a/src/evalfunc.c b/src/evalfunc.c index 04967efc3..12f7a88b0 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -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); } /* diff --git a/src/filepath.c b/src/filepath.c index d514aaf8e..3dd71bc40 100644 --- a/src/filepath.c +++ b/src/filepath.c @@ -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; diff --git a/src/proto/eval.pro b/src/proto/eval.pro index 7247265aa..e945a284c 100644 --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -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 : */ diff --git a/src/version.c b/src/version.c index 3ccae20d7..ce6c38a32 100644 --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 870, /**/ 869, /**/ -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/vim_dev/E1tD7Rj-005Cd5-T7%40256bit.org.