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

Commit: 
https://github.com/vim/vim/commit/38b9f45253f582ab63174376e321092f8a9a7808
Author: John Marriott <basil...@internode.on.net>
Date:   Thu Apr 25 21:39:18 2024 +0200

    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 <basil...@internode.on.net>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/ops.c b/src/ops.c
index 0ab0d005d..e3e782756 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 
 or 
 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 124fb664c..11e18ede2 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 */
+/**/
+    373,
 /**/
     372,
 /**/

-- 
-- 
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 on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1s051m-00EhvF-5H%40256bit.org.

Raspunde prin e-mail lui