0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 9.1.0373: ops.c code uses too many strlen() calls

Problem:  ops.c code uses too many strlen() calls
Solution: Refactor code and remove more strlen() calls
          (John Marriott)

closes: #14598

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-04-25 21:39:18 +02:00
committed by Christian Brabandt
parent f68517c167
commit 38b9f45253
2 changed files with 62 additions and 47 deletions

107
src/ops.c
View File

@@ -281,6 +281,7 @@ shift_block(oparg_T *oap, int amount)
int oldstate = State; int oldstate = State;
int total; int total;
char_u *newp, *oldp; char_u *newp, *oldp;
size_t newlen, oldlen;
int oldcol = curwin->w_cursor.col; int oldcol = curwin->w_cursor.col;
int sw_val = (int)get_sw_value_indent(curbuf); int sw_val = (int)get_sw_value_indent(curbuf);
int ts_val = (int)curbuf->b_p_ts; int ts_val = (int)curbuf->b_p_ts;
@@ -288,7 +289,7 @@ shift_block(oparg_T *oap, int amount)
int incr; int incr;
colnr_T ws_vcol; colnr_T ws_vcol;
int added; int added;
unsigned new_line_len; // the length of the line after the size_t new_line_len; // the length of the line after the
// block shift // block shift
#ifdef FEAT_RIGHTLEFT #ifdef FEAT_RIGHTLEFT
int old_p_ri = p_ri; int old_p_ri = p_ri;
@@ -307,6 +308,7 @@ shift_block(oparg_T *oap, int amount)
return; // multiplication overflow return; // multiplication overflow
oldp = ml_get_curline(); oldp = ml_get_curline();
oldlen = ml_get_curline_len();
if (!left) if (!left)
{ {
@@ -369,15 +371,16 @@ shift_block(oparg_T *oap, int amount)
// if we're splitting a TAB, allow for it // if we're splitting a TAB, allow for it
bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0); bd.textcol -= bd.pre_whitesp_c - (bd.startspaces != 0);
new_line_len = bd.textcol + tabs + spaces + (int)STRLEN(bd.textstart); new_line_len = bd.textcol + tabs + spaces + (oldlen - (bd.textstart - oldp));
newp = alloc(new_line_len + 1); newp = alloc(new_line_len + 1);
if (newp == NULL) if (newp == NULL)
return; return;
mch_memmove(newp, oldp, (size_t)bd.textcol); mch_memmove(newp, oldp, (size_t)bd.textcol);
vim_memset(newp + bd.textcol, TAB, (size_t)tabs); newlen = bd.textcol;
vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces); vim_memset(newp + newlen, TAB, (size_t)tabs);
// Note that STRMOVE() copies the trailing NUL. newlen += tabs;
STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart); vim_memset(newp + newlen, ' ', (size_t)spaces);
STRCPY(newp + newlen + spaces, bd.textstart);
} }
else // left else // left
{ {
@@ -387,11 +390,13 @@ shift_block(oparg_T *oap, int amount)
// copied verbatim // copied verbatim
colnr_T verbatim_copy_width;// the (displayed) width of this part colnr_T verbatim_copy_width;// the (displayed) width of this part
// of line // of line
unsigned fill; // nr of spaces that replace a TAB size_t fill; // nr of spaces that replace a TAB
size_t block_space_width; size_t block_space_width;
size_t shift_amount; size_t shift_amount;
char_u *non_white = bd.textstart; char_u *non_white = bd.textstart;
colnr_T non_white_col; colnr_T non_white_col;
size_t fixedlen; // length of string left of the shift
// position (ie the string not being shifted)
chartabsize_T cts; chartabsize_T cts;
/* /*
@@ -463,21 +468,27 @@ shift_block(oparg_T *oap, int amount)
// - the beginning of the original line up to "verbatim_copy_end", // - the beginning of the original line up to "verbatim_copy_end",
// - "fill" number of spaces, // - "fill" number of spaces,
// - the rest of the line, pointed to by non_white. // - the rest of the line, pointed to by non_white.
new_line_len = (unsigned)(verbatim_copy_end - oldp) fixedlen = verbatim_copy_end - oldp;
+ fill new_line_len = fixedlen + fill + (oldlen - (non_white - oldp));
+ (unsigned)STRLEN(non_white);
newp = alloc(new_line_len + 1); newp = alloc(new_line_len + 1);
if (newp == NULL) if (newp == NULL)
return; return;
mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp)); mch_memmove(newp, oldp, fixedlen);
vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill); newlen = fixedlen;
// Note that STRMOVE() copies the trailing NUL. vim_memset(newp + newlen, ' ', (size_t)fill);
STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white); STRCPY(newp + newlen + fill, non_white);
} }
// replace the line // replace the line
added = new_line_len - ml_get_curline_len();
ml_replace(curwin->w_cursor.lnum, newp, FALSE); ml_replace(curwin->w_cursor.lnum, newp, FALSE);
// compute the number of bytes added or subtracted.
// note new_line_len and oldlen are unsigned so we have
// to be careful about how we calculate this.
if (new_line_len >= oldlen)
added = (int)(new_line_len - oldlen);
else
added = 0 - (int)(oldlen - new_line_len);
inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added); inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added);
State = oldstate; State = oldstate;
curwin->w_cursor.col = oldcol; curwin->w_cursor.col = oldcol;
@@ -494,6 +505,7 @@ shift_block(oparg_T *oap, int amount)
block_insert( block_insert(
oparg_T *oap, oparg_T *oap,
char_u *s, char_u *s,
size_t slen,
int b_insert, int b_insert,
struct block_def *bdp) struct block_def *bdp)
{ {
@@ -502,13 +514,11 @@ block_insert(
int spaces = 0; // non-zero if cutting a TAB int spaces = 0; // non-zero if cutting a TAB
colnr_T offset; // pointer along new line colnr_T offset; // pointer along new line
colnr_T startcol; // column where insert starts colnr_T startcol; // column where insert starts
unsigned s_len; // STRLEN(s)
char_u *newp, *oldp; // new, old lines char_u *newp, *oldp; // new, old lines
linenr_T lnum; // loop var linenr_T lnum; // loop var
int oldstate = State; int oldstate = State;
State = MODE_INSERT; // don't want MODE_REPLACE for State State = MODE_INSERT; // don't want MODE_REPLACE for State
s_len = (unsigned)STRLEN(s);
for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++) for (lnum = oap->start.lnum + 1; lnum <= oap->end.lnum; lnum++)
{ {
@@ -554,7 +564,7 @@ block_insert(
spaces = 0; spaces = 0;
// Make sure the allocated size matches what is actually copied below. // Make sure the allocated size matches what is actually copied below.
newp = alloc(ml_get_len(lnum) + spaces + s_len newp = alloc(ml_get_len(lnum) + spaces + slen
+ (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0) + (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0)
+ count + 1); + count + 1);
if (newp == NULL) if (newp == NULL)
@@ -569,8 +579,8 @@ block_insert(
startcol = offset + spaces; startcol = offset + spaces;
// copy the new text // copy the new text
mch_memmove(newp + startcol, s, (size_t)s_len); mch_memmove(newp + startcol, s, slen);
offset += s_len; offset += slen;
if (spaces > 0 && !bdp->is_short) if (spaces > 0 && !bdp->is_short)
{ {
@@ -591,13 +601,13 @@ block_insert(
if (spaces > 0) if (spaces > 0)
offset += count; offset += count;
STRMOVE(newp + offset, oldp); STRCPY(newp + offset, oldp);
ml_replace(lnum, newp, FALSE); ml_replace(lnum, newp, FALSE);
if (b_insert) if (b_insert)
// correct any text properties // correct any text properties
inserted_bytes(lnum, startcol, s_len); inserted_bytes(lnum, startcol, slen);
if (lnum == oap->end.lnum) if (lnum == oap->end.lnum)
{ {
@@ -809,8 +819,8 @@ op_delete(oparg_T *oap)
vim_memset(newp + bd.textcol, ' ', vim_memset(newp + bd.textcol, ' ',
(size_t)(bd.startspaces + bd.endspaces)); (size_t)(bd.startspaces + bd.endspaces));
// copy the part after the deleted part // copy the part after the deleted part
oldp += bd.textcol + bd.textlen; STRCPY(newp + bd.textcol + bd.startspaces + bd.endspaces,
STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp); oldp + bd.textcol + bd.textlen);
// replace the line // replace the line
ml_replace(lnum, newp, FALSE); ml_replace(lnum, newp, FALSE);
@@ -1030,7 +1040,7 @@ op_replace(oparg_T *oap, int c)
int n, numc; int n, numc;
int num_chars; int num_chars;
char_u *newp, *oldp; char_u *newp, *oldp;
size_t oldlen; size_t newlen, oldlen;
struct block_def bd; struct block_def bd;
char_u *after_p = NULL; char_u *after_p = NULL;
int had_ctrl_v_cr = FALSE; int had_ctrl_v_cr = FALSE;
@@ -1122,9 +1132,10 @@ op_replace(oparg_T *oap, int c)
vim_memset(newp, NUL, (size_t)(oldlen + 1 + n)); vim_memset(newp, NUL, (size_t)(oldlen + 1 + n));
// copy up to deleted part // copy up to deleted part
mch_memmove(newp, oldp, (size_t)bd.textcol); mch_memmove(newp, oldp, (size_t)bd.textcol);
oldp += bd.textcol + bd.textlen; newlen = bd.textcol;
// insert pre-spaces // insert pre-spaces
vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); vim_memset(newp + newlen, ' ', (size_t)bd.startspaces);
newlen += bd.startspaces;
// insert replacement chars CHECK FOR ALLOCATED SPACE // insert replacement chars CHECK FOR ALLOCATED SPACE
// REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR // REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR
// literally. // literally.
@@ -1132,27 +1143,31 @@ op_replace(oparg_T *oap, int c)
{ {
if (has_mbyte) if (has_mbyte)
{ {
n = (int)STRLEN(newp);
while (--num_chars >= 0) while (--num_chars >= 0)
n += (*mb_char2bytes)(c, newp + n); newlen += (*mb_char2bytes)(c, newp + newlen);
} }
else else
vim_memset(newp + STRLEN(newp), c, (size_t)numc); {
vim_memset(newp + newlen, c, (size_t)numc);
newlen += numc;
}
if (!bd.is_short) if (!bd.is_short)
{ {
// insert post-spaces // insert post-spaces
vim_memset(newp + STRLEN(newp), ' ', (size_t)bd.endspaces); vim_memset(newp + newlen, ' ', (size_t)bd.endspaces);
// copy the part after the changed part // copy the part after the changed part
STRMOVE(newp + STRLEN(newp), oldp); STRCPY(newp + newlen + bd.endspaces,
oldp + bd.textcol + bd.textlen);
} }
} }
else else
{ {
// Replacing with \r or \n means splitting the line. // Replacing with \r or \n means splitting the line.
after_p = alloc(oldlen + 1 + n - STRLEN(newp)); after_p = alloc(oldlen + 1 + n - newlen);
if (after_p != NULL) if (after_p != NULL)
STRMOVE(after_p, oldp); STRCPY(after_p, oldp + bd.textcol + bd.textlen);
} }
// replace the line // replace the line
ml_replace(curwin->w_cursor.lnum, newp, FALSE); ml_replace(curwin->w_cursor.lnum, newp, FALSE);
if (after_p != NULL) if (after_p != NULL)
@@ -1715,7 +1730,7 @@ op_insert(oparg_T *oap, long count1)
// block handled here // block handled here
if (u_save(oap->start.lnum, if (u_save(oap->start.lnum,
(linenr_T)(oap->end.lnum + 1)) == OK) (linenr_T)(oap->end.lnum + 1)) == OK)
block_insert(oap, ins_text, (oap->op_type == OP_INSERT), block_insert(oap, ins_text, ins_len, (oap->op_type == OP_INSERT),
&bd); &bd);
curwin->w_cursor.col = oap->start.col; curwin->w_cursor.col = oap->start.col;
@@ -1736,9 +1751,7 @@ op_change(oparg_T *oap)
{ {
colnr_T l; colnr_T l;
int retval; int retval;
long offset;
linenr_T linenr; linenr_T linenr;
long ins_len;
long pre_textlen = 0; long pre_textlen = 0;
long pre_indent = 0; long pre_indent = 0;
char_u *firstline; char_u *firstline;
@@ -1798,6 +1811,8 @@ op_change(oparg_T *oap)
*/ */
if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int) if (oap->block_mode && oap->start.lnum != oap->end.lnum && !got_int)
{ {
size_t ins_len;
// Auto-indenting may have changed the indent. If the cursor was past // Auto-indenting may have changed the indent. If the cursor was past
// the indent, exclude that indent change from the inserted text. // the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum); firstline = ml_get(oap->start.lnum);
@@ -1816,7 +1831,7 @@ op_change(oparg_T *oap)
// copy of the inserted text. // copy of the inserted text.
if ((ins_text = alloc(ins_len + 1)) != NULL) if ((ins_text = alloc(ins_len + 1)) != NULL)
{ {
vim_strncpy(ins_text, firstline + bd.textcol, (size_t)ins_len); vim_strncpy(ins_text, firstline + bd.textcol, ins_len);
for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum; for (linenr = oap->start.lnum + 1; linenr <= oap->end.lnum;
linenr++) linenr++)
{ {
@@ -1824,6 +1839,7 @@ op_change(oparg_T *oap)
if (!bd.is_short || virtual_op) if (!bd.is_short || virtual_op)
{ {
pos_T vpos; pos_T vpos;
size_t newlen;
// If the block starts in virtual space, count the // If the block starts in virtual space, count the
// initial coladd offset as part of "startspaces" // initial coladd offset as part of "startspaces"
@@ -1835,19 +1851,16 @@ op_change(oparg_T *oap)
else else
vpos.coladd = 0; vpos.coladd = 0;
oldp = ml_get(linenr); oldp = ml_get(linenr);
newp = alloc(ml_get_len(linenr) newp = alloc(ml_get_len(linenr) + vpos.coladd + ins_len + 1);
+ vpos.coladd + ins_len + 1);
if (newp == NULL) if (newp == NULL)
continue; continue;
// copy up to block start // copy up to block start
mch_memmove(newp, oldp, (size_t)bd.textcol); mch_memmove(newp, oldp, (size_t)bd.textcol);
offset = bd.textcol; newlen = bd.textcol;
vim_memset(newp + offset, ' ', (size_t)vpos.coladd); vim_memset(newp + newlen, ' ', (size_t)vpos.coladd);
offset += vpos.coladd; newlen += vpos.coladd;
mch_memmove(newp + offset, ins_text, (size_t)ins_len); mch_memmove(newp + newlen, ins_text, ins_len);
offset += ins_len; STRCPY(newp + newlen + ins_len, oldp + bd.textcol);
oldp += bd.textcol;
STRMOVE(newp + offset, oldp);
ml_replace(linenr, newp, FALSE); ml_replace(linenr, newp, FALSE);
#ifdef FEAT_PROP_POPUP #ifdef FEAT_PROP_POPUP
// Shift the properties for linenr as edit() would do. // Shift the properties for linenr as edit() would do.

View File

@@ -704,6 +704,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 */
/**/
373,
/**/ /**/
372, 372,
/**/ /**/