summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Marriott <basilisk@internode.on.net>2024-04-25 21:39:18 +0200
committerChristian Brabandt <cb@256bit.org>2024-04-25 21:39:18 +0200
commit38b9f45253f582ab63174376e321092f8a9a7808 (patch)
tree2c42c87a7da3b5decce7055cd5de0a879e2eb4de
parentf68517c1671dfedcc1555da50bc0b3de6d2842f6 (diff)
patch 9.1.0373: ops.c code uses too many strlen() callsv9.1.0373
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>
-rw-r--r--src/ops.c107
-rw-r--r--src/version.c2
2 files changed, 62 insertions, 47 deletions
diff --git a/src/ops.c b/src/ops.c
index 0ab0d005db..e3e782756e 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -281,6 +281,7 @@ shift_block(oparg_T *oap, int amount)
int oldstate = State;
int total;
char_u *newp, *oldp;
+ size_t newlen, oldlen;
int oldcol = curwin->w_cursor.col;
int sw_val = (int)get_sw_value_indent(curbuf);
int ts_val = (int)curbuf->b_p_ts;
@@ -288,7 +289,7 @@ shift_block(oparg_T *oap, int amount)
int incr;
colnr_T ws_vcol;
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
#ifdef FEAT_RIGHTLEFT
int old_p_ri = p_ri;
@@ -307,6 +308,7 @@ shift_block(oparg_T *oap, int amount)
return; // multiplication overflow
oldp = ml_get_curline();
+ oldlen = ml_get_curline_len();
if (!left)
{
@@ -369,15 +371,16 @@ shift_block(oparg_T *oap, int amount)
// if we're splitting a TAB, allow for it
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);
if (newp == NULL)
return;
mch_memmove(newp, oldp, (size_t)bd.textcol);
- vim_memset(newp + bd.textcol, TAB, (size_t)tabs);
- vim_memset(newp + bd.textcol + tabs, ' ', (size_t)spaces);
- // Note that STRMOVE() copies the trailing NUL.
- STRMOVE(newp + bd.textcol + tabs + spaces, bd.textstart);
+ newlen = bd.textcol;
+ vim_memset(newp + newlen, TAB, (size_t)tabs);
+ newlen += tabs;
+ vim_memset(newp + newlen, ' ', (size_t)spaces);
+ STRCPY(newp + newlen + spaces, bd.textstart);
}
else // left
{
@@ -387,11 +390,13 @@ shift_block(oparg_T *oap, int amount)
// copied verbatim
colnr_T verbatim_copy_width;// the (displayed) width of this part
// 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 shift_amount;
char_u *non_white = bd.textstart;
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;
/*
@@ -463,21 +468,27 @@ shift_block(oparg_T *oap, int amount)
// - the beginning of the original line up to "verbatim_copy_end",
// - "fill" number of spaces,
// - the rest of the line, pointed to by non_white.
- new_line_len = (unsigned)(verbatim_copy_end - oldp)
- + fill
- + (unsigned)STRLEN(non_white);
+ fixedlen = verbatim_copy_end - oldp;
+ new_line_len = fixedlen + fill + (oldlen - (non_white - oldp));
newp = alloc(new_line_len + 1);
if (newp == NULL)
return;
- mch_memmove(newp, oldp, (size_t)(verbatim_copy_end - oldp));
- vim_memset(newp + (verbatim_copy_end - oldp), ' ', (size_t)fill);
- // Note that STRMOVE() copies the trailing NUL.
- STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
+ mch_memmove(newp, oldp, fixedlen);
+ newlen = fixedlen;
+ vim_memset(newp + newlen, ' ', (size_t)fill);
+ STRCPY(newp + newlen + fill, non_white);
}
// replace the line
- added = new_line_len - ml_get_curline_len();
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);
State = oldstate;
curwin->w_cursor.col = oldcol;
@@ -494,6 +505,7 @@ shift_block(oparg_T *oap, int amount)
block_insert(
oparg_T *oap,
char_u *s,
+ size_t slen,
int b_insert,
struct block_def *bdp)
{
@@ -502,13 +514,11 @@ block_insert(
int spaces = 0; // non-zero if cutting a TAB
colnr_T offset; // pointer along new line
colnr_T startcol; // column where insert starts
- unsigned s_len; // STRLEN(s)
char_u *newp, *oldp; // new, old lines
linenr_T lnum; // loop var
int oldstate = 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++)
{
@@ -554,7 +564,7 @@ block_insert(
spaces = 0;
// 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)
+ count + 1);
if (newp == NULL)
@@ -569,8 +579,8 @@ block_insert(
startcol = offset + spaces;
// copy the new text
- mch_memmove(newp + startcol, s, (size_t)s_len);
- offset += s_len;
+ mch_memmove(newp + startcol, s, slen);
+ offset += slen;
if (spaces > 0 && !bdp->is_short)
{
@@ -591,13 +601,13 @@ block_insert(
if (spaces > 0)
offset += count;
- STRMOVE(newp + offset, oldp);
+ STRCPY(newp + offset, oldp);
ml_replace(lnum, newp, FALSE);
if (b_insert)
// correct any text properties
- inserted_bytes(lnum, startcol, s_len);
+ inserted_bytes(lnum, startcol, slen);
if (lnum == oap->end.lnum)
{
@@ -809,8 +819,8 @@ op_delete(oparg_T *oap)
vim_memset(newp + bd.textcol, ' ',
(size_t)(bd.startspaces + bd.endspaces));
// copy the part after the deleted part
- oldp += bd.textcol + bd.textlen;
- STRMOVE(newp + bd.textcol + bd.startspaces + bd.endspaces, oldp);
+ STRCPY(newp + bd.textcol + bd.startspaces + bd.endspaces,
+ oldp + bd.textcol + bd.textlen);
// replace the line
ml_replace(lnum, newp, FALSE);
@@ -1030,7 +1040,7 @@ op_replace(oparg_T *oap, int c)
int n, numc;
int num_chars;
char_u *newp, *oldp;
- size_t oldlen;
+ size_t newlen, oldlen;
struct block_def bd;
char_u *after_p = NULL;
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));
// copy up to deleted part
mch_memmove(newp, oldp, (size_t)bd.textcol);
- oldp += bd.textcol + bd.textlen;
+ newlen = bd.textcol;
// 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
// REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR
// literally.
@@ -1132,27 +1143,31 @@ op_replace(oparg_T *oap, int c)
{
if (has_mbyte)
{
- n = (int)STRLEN(newp);
while (--num_chars >= 0)
- n += (*mb_char2bytes)(c, newp + n);
+ newlen += (*mb_char2bytes)(c, newp + newlen);
}
else
- vim_memset(newp + STRLEN(newp), c, (size_t)numc);
+ {
+ vim_memset(newp + newlen, c, (size_t)numc);
+ newlen += numc;
+ }
if (!bd.is_short)
{
// 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
- STRMOVE(newp + STRLEN(newp), oldp);
+ STRCPY(newp + newlen + bd.endspaces,
+ oldp + bd.textcol + bd.textlen);
}
}
else
{
// 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)
- STRMOVE(after_p, oldp);
+ STRCPY(after_p, oldp + bd.textcol + bd.textlen);
}
+
// replace the line
ml_replace(curwin->w_cursor.lnum, newp, FALSE);
if (after_p != NULL)
@@ -1715,7 +1730,7 @@ op_insert(oparg_T *oap, long count1)
// block handled here
if (u_save(oap->start.lnum,
(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);
curwin->w_cursor.col = oap->start.col;
@@ -1736,9 +1751,7 @@ op_change(oparg_T *oap)
{
colnr_T l;
int retval;
- long offset;
linenr_T linenr;
- long ins_len;
long pre_textlen = 0;
long pre_indent = 0;
char_u *firstline;
@@ -1798,6 +1811,8 @@ op_change(oparg_T *oap)
*/
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
// the indent, exclude that indent change from the inserted text.
firstline = ml_get(oap->start.lnum);
@@ -1816,7 +1831,7 @@ op_change(oparg_T *oap)
// copy of the inserted text.
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;
linenr++)
{
@@ -1824,6 +1839,7 @@ op_change(oparg_T *oap)
if (!bd.is_short || virtual_op)
{
pos_T vpos;
+ size_t newlen;
// If the block starts in virtual space, count the
// initial coladd offset as part of "startspaces"
@@ -1835,19 +1851,16 @@ op_change(oparg_T *oap)
else
vpos.coladd = 0;
oldp = ml_get(linenr);
- newp = alloc(ml_get_len(linenr)
- + vpos.coladd + ins_len + 1);
+ newp = alloc(ml_get_len(linenr) + vpos.coladd + ins_len + 1);
if (newp == NULL)
continue;
// copy up to block start
mch_memmove(newp, oldp, (size_t)bd.textcol);
- offset = bd.textcol;
- vim_memset(newp + offset, ' ', (size_t)vpos.coladd);
- offset += vpos.coladd;
- mch_memmove(newp + offset, ins_text, (size_t)ins_len);
- offset += ins_len;
- oldp += bd.textcol;
- STRMOVE(newp + offset, oldp);
+ newlen = bd.textcol;
+ vim_memset(newp + newlen, ' ', (size_t)vpos.coladd);
+ newlen += vpos.coladd;
+ mch_memmove(newp + newlen, ins_text, ins_len);
+ STRCPY(newp + newlen + ins_len, oldp + bd.textcol);
ml_replace(linenr, newp, FALSE);
#ifdef FEAT_PROP_POPUP
// Shift the properties for linenr as edit() would do.
diff --git a/src/version.c b/src/version.c
index 124fb664c3..11e18ede29 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 373,
+/**/
372,
/**/
371,