patch 9.1.0172: More code can use ml_get_buf_len() instead of STRLEN()

Commit: 
https://github.com/vim/vim/commit/94b7c3233ef534acc669b3083ed1fe59cf3a090b
Author: zeertzjq <zeert...@outlook.com>
Date:   Tue Mar 12 21:50:32 2024 +0100

    patch 9.1.0172: More code can use ml_get_buf_len() instead of STRLEN()
    
    Problem:  More code can use ml_get_buf_len() instead of STRLEN().
    Solution: Change more STRLEN() calls to ml_get_buf_len().  Also do not
              set ml_line_textlen in ml_replace_len() if "has_props" is set,
              because "len_arg" also includes the size of text properties in
              that case. (zeertzjq)
    
    closes: #14183
    
    Signed-off-by: zeertzjq <zeert...@outlook.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/buffer.c b/src/buffer.c
index 36396e8d2..243593a52 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4221,7 +4221,7 @@ build_stl_str_hl(
     stl_hlrec_T **tabtab)      // return: tab page nrs (can be NULL)
 {
     linenr_T   lnum;
-    size_t     len;
+    colnr_T    len;
     char_u     *p;
     char_u     *s;
     char_u     *t;
@@ -4328,12 +4328,12 @@ build_stl_str_hl(
 
     // Get the byte value now, in case we need it below. This is more efficient
     // than making a copy of the line.
-    len = STRLEN(p);
-    if (wp->w_cursor.col > (colnr_T)len)
+    len = ml_get_buf_len(wp->w_buffer, lnum);
+    if (wp->w_cursor.col > len)
     {
        // Line may have changed since checking the cursor column, or the lnum
        // was adjusted above.
-       wp->w_cursor.col = (colnr_T)len;
+       wp->w_cursor.col = len;
        wp->w_cursor.coladd = 0;
        byteval = 0;
     }
diff --git a/src/channel.c b/src/channel.c
index 8d850c656..b99b3a90a 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -1493,7 +1493,7 @@ channel_set_req_callback(
 write_buf_line(buf_T *buf, linenr_T lnum, channel_T *channel)
 {
     char_u  *line = ml_get_buf(buf, lnum, FALSE);
-    int            len = (int)STRLEN(line);
+    int            len = ml_get_buf_len(buf, lnum);
     char_u  *p;
     int            i;
 
diff --git a/src/charset.c b/src/charset.c
index 9f4c0ae82..5ae90da5d 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1690,7 +1690,7 @@ getvvcol(
        endadd = 0;
        // Cannot put the cursor on part of a wide character.
        ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
-       if (pos->col < (colnr_T)STRLEN(ptr))
+       if (pos->col < ml_get_buf_len(wp->w_buffer, pos->lnum))
        {
            int c = (*mb_ptr2char)(ptr + pos->col);
 
diff --git a/src/diff.c b/src/diff.c
index d2089dc15..e1c8f58de 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -762,7 +762,7 @@ diff_write_buffer(buf_T *buf, diffin_T *din)
 
     // xdiff requires one big block of memory with all the text.
     for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
-       len += (long)STRLEN(ml_get_buf(buf, lnum, FALSE)) + 1;
+       len += ml_get_buf_len(buf, lnum) + 1;
     ptr = alloc(len);
     if (ptr == NULL)
     {
diff --git a/src/drawline.c b/src/drawline.c
index 0bb7ed57d..629d66f1c 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -1533,7 +1533,7 @@ win_line(
        }
        else
        {
-           v = (long)STRLEN(line);
+           v = ml_get_buf_len(wp->w_buffer, lnum);
            if (v < SPWORDLEN)
            {
                // Short line, use it completely and append the start of the
@@ -1570,7 +1570,7 @@ win_line(
        // find start of trailing whitespace
        if (wp->w_lcs_chars.trail)
        {
-           trailcol = (colnr_T)STRLEN(ptr);
+           trailcol = ml_get_buf_len(wp->w_buffer, lnum);
            while (trailcol > (colnr_T)0 && VIM_ISWHITE(ptr[trailcol - 1]))
                --trailcol;
            trailcol += (colnr_T)(ptr - line);
diff --git a/src/drawscreen.c b/src/drawscreen.c
index 5fb37a984..3d6c230c1 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -1300,7 +1300,7 @@ fold_line(
                        && (lnume < bot->lnum
                            || (lnume == bot->lnum
                                && (bot->col - (*p_sel == 'e'))
-               >= (colnr_T)STRLEN(ml_get_buf(wp->w_buffer, lnume, FALSE)))))))
+                                   >= ml_get_buf_len(wp->w_buffer, lnume))))))
        {
            if (VIsual_mode == Ctrl_V)
            {
diff --git a/src/edit.c b/src/edit.c
index f700c6a12..69ec25518 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -3222,7 +3222,7 @@ replace_do_bs(int limit_col)
        {
            // Do not adjust text properties for individual delete and insert
            // operations, do it afterwards on the resulting text.
-           len_before = STRLEN(ml_get_curline());
+           len_before = ml_get_curline_len();
            ++text_prop_frozen;
        }
 #endif
@@ -3237,14 +3237,14 @@ replace_do_bs(int limit_col)
        {
            (void)del_char_after_col(limit_col);
            if (State & VREPLACE_FLAG)
-               orig_len = (int)STRLEN(ml_get_cursor());
+               orig_len = ml_get_cursor_len();
            replace_push(cc);
        }
        else
        {
            pchar_cursor(cc);
            if (State & VREPLACE_FLAG)
-               orig_len = (int)STRLEN(ml_get_cursor()) - 1;
+               orig_len = ml_get_cursor_len() - 1;
        }
        replace_pop_ins();
 
@@ -3252,7 +3252,7 @@ replace_do_bs(int limit_col)
        {
            // Get the number of screen cells used by the inserted characters
            p = ml_get_cursor();
-           ins_len = (int)STRLEN(p) - orig_len;
+           ins_len = ml_get_cursor_len() - orig_len;
            vcol = start_vcol;
            for (i = 0; i < ins_len; ++i)
            {
@@ -3278,7 +3278,7 @@ replace_do_bs(int limit_col)
 #ifdef FEAT_PROP_POPUP
        if (curbuf->b_has_textprop)
        {
-           size_t len_now = STRLEN(ml_get_curline());
+           size_t len_now = ml_get_curline_len();
 
            --text_prop_frozen;
            adjust_prop_columns(curwin->w_cursor.lnum, curwin->w_cursor.col,
@@ -4068,7 +4068,7 @@ ins_bs(
                               (linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL)
                return FALSE;
            --Insstart.lnum;
-           Insstart.col = (colnr_T)STRLEN(ml_get(Insstart.lnum));
+           Insstart.col = ml_get_len(Insstart.lnum);
        }
        /*
         * In replace mode:
@@ -5174,7 +5174,7 @@ ins_eol(int c)
     // NL in reverse insert will always start in the end of
     // current line.
     if (revins_on)
-       curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor());
+       curwin->w_cursor.col += ml_get_cursor_len();
 #endif
 
     AppendToRedobuff(NL_STR);
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index a12d819b3..d0fc928e6 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -489,7 +489,7 @@ ex_sort(exarg_T *eap)
     for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
     {
        s = ml_get(lnum);
-       len = (int)STRLEN(s);
+       len = ml_get_len(lnum);
        if (maxlen < len)
            maxlen = len;
 
@@ -691,7 +691,7 @@ do_move(linenr_T line1, linenr_T line2, linenr_T dest)
        return FAIL;
     for (extra = 0, l = line1; l <= line2; l++)
     {
-       str = vim_strsave(ml_get(l + extra));
+       str = vim_strnsave(ml_get(l + extra), ml_get_len(l + extra));
        if (str != NULL)
        {
            ml_append(dest + l - line1, str, (colnr_T)0, FALSE);
@@ -824,9 +824,9 @@ ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
     curwin->w_cursor.lnum = n;
     while (line1 <= line2)
     {
-       // need to use vim_strsave() because the line will be unlocked within
+       // need to make a copy because the line will be unlocked within
        // ml_append()
-       p = vim_strsave(ml_get(line1));
+       p = vim_strnsave(ml_get(line1), ml_get_len(line1));
        if (p != NULL)
        {
            ml_append(curwin->w_cursor.lnum, p, (colnr_T)0, FALSE);
@@ -4225,7 +4225,8 @@ ex_substitute(exarg_T *eap)
 
                if (sub_firstline == NULL)
                {
-                   sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+                   sub_firstline = vim_strnsave(ml_get(sub_firstlnum),
+                                                   ml_get_len(sub_firstlnum));
                    if (sub_firstline == NULL)
                    {
                        vim_free(new_start);
@@ -4379,7 +4380,8 @@ ex_substitute(exarg_T *eap)
                                // really update the line, it would change
                                // what matches.  Temporarily replace the line
                                // and change it back afterwards.
-                               orig_line = vim_strsave(ml_get(lnum));
+                               orig_line = vim_strnsave(ml_get(lnum),
+                                                            ml_get_len(lnum));
                                if (orig_line != NULL)
                                {
                                    char_u *new_line = concat_str(new_start,
@@ -4725,7 +4727,8 @@ ex_substitute(exarg_T *eap)
                {
                    sub_firstlnum += nmatch - 1;
                    vim_free(sub_firstline);
-                   sub_firstline = vim_strsave(ml_get(sub_firstlnum));
+                   sub_firstline = vim_strnsave(ml_get(sub_firstlnum),
+                                                   ml_get_len(sub_firstlnum));
                    // When going beyond the last line, stop substituting.
                    if (sub_firstlnum <= line2)
                        do_again = TRUE;
diff --git a/src/fileio.c b/src/fileio.c
index ad09c5a22..53bfbeadf 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1246,7 +1246,7 @@ retry:
                        for (;;)
                        {
                            p = ml_get(read_buf_lnum) + read_buf_col;
-                           n = (int)STRLEN(p);
+                           n = ml_get_len(read_buf_lnum) - read_buf_col;
                            if ((int)tlen + n + 1 > size)
                            {
                                // Filled up to "size", append partial line.
diff --git a/src/fold.c b/src/fold.c
index 5c41ed1b0..420bcf1b8 100644
--- a/src/fold.c
+++ b/src/fold.c
@@ -1061,7 +1061,6 @@ find_wl_entry(win_T *win, linenr_T lnum)
 foldAdjustVisual(void)
 {
     pos_T      *start, *end;
-    char_u     *ptr;
 
     if (!VIsual_active || !hasAnyFolding(curwin))
        return;
@@ -1082,8 +1081,7 @@ foldAdjustVisual(void)
     if (!hasFolding(end->lnum, NULL, &end->lnum))
        return;
 
-    ptr = ml_get(end->lnum);
-    end->col = (colnr_T)STRLEN(ptr);
+    end->col = ml_get_len(end->lnum);
     if (end->col > 0 && *p_sel == 'o')
        --end->col;
     // prevent cursor from moving on the trail byte
@@ -1799,7 +1797,7 @@ foldAddMarker(linenr_T lnum, char_u *marker, int 
markerlen)
 
     // Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end
     line = ml_get(lnum);
-    line_len = (int)STRLEN(line);
+    line_len = ml_get_len(lnum);
 
     if (u_save(lnum - 1, lnum + 1) != OK)
        return;
@@ -1887,7 +1885,7 @@ foldDelMarker(linenr_T lnum, char_u *marker, int 
markerlen)
            if (u_save(lnum - 1, lnum + 1) == OK)
            {
                // Make new line: text-before-marker + text-after-marker
-               newline = alloc(STRLEN(line) - len + 1);
+               newline = alloc(ml_get_len(lnum) - len + 1);
                if (newline != NULL)
                {
                    STRNCPY(newline, line, p - line);
diff --git a/src/help.c b/src/help.c
index c33985ed9..a792bf3cc 100644
--- a/src/help.c
+++ b/src/help.c
@@ -720,7 +720,7 @@ fix_help_buffer(void)
        for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
        {
            line = ml_get_buf(curbuf, lnum, FALSE);
-           len = (int)STRLEN(line);
+           len = ml_get_buf_len(curbuf, lnum);
            if (in_example && len > 0 && !VIM_ISWHITE(line[0]))
            {
                // End of example: non-white or '<' in first column.
diff --git a/src/indent.c b/src/indent.c
index 1087bad3e..56032fadb 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1609,7 +1609,7 @@ copy_indent(int size, char_u *src)
        {
            // Allocate memory for the result: the copied indent, new indent
            // and the rest of the line.
-           line_len = (int)STRLEN(ml_get_curline()) + 1;
+           line_len = ml_get_curline_len() + 1;
            line = alloc(ind_len + line_len);
            if (line == NULL)
                return FALSE;
diff --git a/src/insexpand.c b/src/insexpand.c
index 0847b6c05..5d82e30f1 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -3297,8 +3297,7 @@ process_next_cpt_value(
            // buffer, so that word at start of buffer is found
            // correctly.
            st->first_match_pos.lnum = st->ins_buf->b_ml.ml_line_count;
-           st->first_match_pos.col =
-               (colnr_T)STRLEN(ml_get(st->first_match_pos.lnum));
+           st->first_match_pos.col = ml_get_len(st->first_match_pos.lnum);
        }
        st->last_match_pos = st->first_match_pos;
        compl_type = 0;
diff --git a/src/mbyte.c b/src/mbyte.c
index d6d81c4c7..d6fb7ecc7 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -4378,7 +4378,7 @@ mb_adjustpos(buf_T *buf, pos_T *lp)
     if (lp->col > 0 || lp->coladd > 1)
     {
        p = ml_get_buf(buf, lp->lnum, FALSE);
-       if (*p == NUL || (int)STRLEN(p) < lp->col)
+       if (*p == NUL || ml_get_buf_len(buf, lp->lnum) < lp->col)
            lp->col = 0;
        else
            lp->col -= (*mb_head_off)(p, p + lp->col);
diff --git a/src/memline.c b/src/memline.c
index 522815526..a1c29cf0e 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -2682,6 +2682,13 @@ ml_get_len(linenr_T lnum)
     return ml_get_buf_len(curbuf, lnum);
 }
 
+// return length (excluding the NUL) of the text after position "pos"
+    colnr_T
+ml_get_pos_len(pos_T *pos)
+{
+    return ml_get_buf_len(curbuf, curwin->w_cursor.lnum) - pos->col;
+}
+
 // return length (excluding the NUL) of the cursor line
     colnr_T
 ml_get_curline_len(void)
@@ -3661,7 +3668,7 @@ ml_replace_len(
 
     curbuf->b_ml.ml_line_ptr = line;
     curbuf->b_ml.ml_line_len = len;
-    curbuf->b_ml.ml_line_textlen = len_arg + !has_props;
+    curbuf->b_ml.ml_line_textlen = !has_props ? len_arg + 1 : 0;
     curbuf->b_ml.ml_line_lnum = lnum;
     curbuf->b_ml.ml_flags = (curbuf->b_ml.ml_flags | ML_LINE_DIRTY) & 
~ML_EMPTY;
 
diff --git a/src/misc2.c b/src/misc2.c
index 611e021cc..6df0d3910 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -130,6 +130,7 @@ coladvance2(
     colnr_T    wcol = wcol_arg;
     int                idx;
     char_u     *line;
+    int                linelen;
     colnr_T    col = 0;
     int                csize = 0;
     int                one_more;
@@ -142,10 +143,11 @@ coladvance2(
                    || (VIsual_active && *p_sel != 'o')
                    || ((get_ve_flags() & VE_ONEMORE) && wcol < MAXCOL);
     line = ml_get_buf(curbuf, pos->lnum, FALSE);
+    linelen = ml_get_buf_len(curbuf, pos->lnum);
 
     if (wcol >= MAXCOL)
     {
-           idx = (int)STRLEN(line) - 1 + one_more;
+           idx = linelen - 1 + one_more;
            col = wcol;
 
            if ((addspaces || finetune) && !VIsual_active)
@@ -255,7 +257,6 @@ coladvance2(
            else
            {
                // Break a tab
-               int     linelen = (int)STRLEN(line);
                int     correct = wcol - col - csize + 1; // negative!!
                char_u  *newline;
                int     t, s = 0;
@@ -412,7 +413,7 @@ dec(pos_T *lp)
     {
        // past end of line
        p = ml_get(lp->lnum);
-       lp->col = (colnr_T)STRLEN(p);
+       lp->col = ml_get_len(lp->lnum);
        if (has_mbyte)
            lp->col -= (*mb_head_off)(p, p + lp->col);
        return 0;
@@ -435,7 +436,7 @@ dec(pos_T *lp)
        // there is a prior line
        lp->lnum--;
        p = ml_get(lp->lnum);
-       lp->col = (colnr_T)STRLEN(p);
+       lp->col = ml_get_len(lp->lnum);
        if (has_mbyte)
            lp->col -= (*mb_head_off)(p, p + lp->col);
        return 1;
@@ -515,7 +516,6 @@ get_cursor_rel_lnum(
     void
 check_pos(buf_T *buf, pos_T *pos)
 {
-    char_u *line;
     colnr_T len;
 
     if (pos->lnum > buf->b_ml.ml_line_count)
@@ -523,8 +523,7 @@ check_pos(buf_T *buf, pos_T *pos)
 
     if (pos->col > 0)
     {
-       line = ml_get_buf(buf, pos->lnum, FALSE);
-       len = (colnr_T)STRLEN(line);
+       len = ml_get_buf_len(buf, pos->lnum);
        if (pos->col > len)
            pos->col = len;
     }
@@ -570,7 +569,7 @@ check_cursor_col_win(win_T *win)
     colnr_T      oldcoladd = win->w_cursor.col + win->w_cursor.coladd;
     unsigned int cur_ve_flags = get_ve_flags();
 
-    len = (colnr_T)STRLEN(ml_get_buf(win->w_buffer, win->w_cursor.lnum, 
FALSE));
+    len = ml_get_buf_len(win->w_buffer, win->w_cursor.lnum);
     if (len == 0)
        win->w_cursor.col = 0;
     else if (win->w_cursor.col >= len)
@@ -649,7 +648,7 @@ check_visual_pos(void)
     }
     else
     {
-       int len = (int)STRLEN(ml_get(VIsual.lnum));
+       int len = ml_get_len(VIsual.lnum);
 
        if (VIsual.col > len)
        {
diff --git a/src/netbeans.c b/src/netbeans.c
index d542b5886..3b6886919 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -932,7 +932,7 @@ nb_partialremove(linenr_T lnum, colnr_T first, colnr_T last)
     int lastbyte = last;
 
     oldtext = ml_get(lnum);
-    oldlen = (int)STRLEN(oldtext);
+    oldlen = ml_get_len(lnum);
     if (first >= (colnr_T)oldlen || oldlen == 0)  // just in case
        return;
     if (lastbyte >= oldlen)
@@ -957,8 +957,8 @@ nb_joinlines(linenr_T first, linenr_T other)
     int len_first, len_other;
     char_u *p;
 
-    len_first = (int)STRLEN(ml_get(first));
-    len_other = (int)STRLEN(ml_get(other));
+    len_first = ml_get_len(first);
+    len_other = ml_get_len(other);
     p = alloc(len_first + len_other + 1);
     if (p == NULL)
        return;
@@ -1402,7 +1402,7 @@ nb_do_cmd(
                        int     col = pos == NULL ? 0 : pos->col;
 
                        // Insert halfway a line.
-                       newline = alloc(STRLEN(oldline) + len + 1);
+                       newline = alloc(ml_get_len(lnum) + len + 1);
                        if (newline != NULL)
                        {
                            mch_memmove(newline, oldline, (size_t)col);
@@ -3314,8 +3314,7 @@ get_buf_size(buf_T *bufp)
        eol_size = 1;
     for (lnum = 1; lnum <= bufp->b_ml.ml_line_count; ++lnum)
     {
-       char_count += (long)STRLEN(ml_get_buf(bufp, lnum, FALSE))
-           + eol_size;
+       char_count += ml_get_buf_len(bufp, lnum) + eol_size;
        // Check for a CTRL-C every 100000 characters
        if (char_count > last_check)
        {
diff --git a/src/ops.c b/src/ops.c
index 57e699150..3216f3c81 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -212,7 +212,7 @@ op_shift(oparg_T *oap, int curs_top, int amount)
        // Set "'[" and "']" marks.
        curbuf->b_op_start = oap->start;
        curbuf->b_op_end.lnum = oap->end.lnum;
-       curbuf->b_op_end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+       curbuf->b_op_end.col = ml_get_len(oap->end.lnum);
        if (curbuf->b_op_end.col > 0)
            --curbuf->b_op_end.col;
     }
@@ -476,7 +476,7 @@ shift_block(oparg_T *oap, int amount)
        STRMOVE(newp + (verbatim_copy_end - oldp) + fill, non_white);
     }
     // replace the line
-    added = new_line_len - (int)STRLEN(oldp);
+    added = new_line_len - ml_get_curline_len();
     ml_replace(curwin->w_cursor.lnum, newp, FALSE);
     inserted_bytes(curwin->w_cursor.lnum, bd.textcol, added);
     State = oldstate;
@@ -554,7 +554,7 @@ block_insert(
            spaces = 0;
 
        // Make sure the allocated size matches what is actually copied below.
-       newp = alloc(STRLEN(oldp) + spaces + s_len
+       newp = alloc(ml_get_len(lnum) + spaces + s_len
                    + (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0)
                                                                  + count + 1);
        if (newp == NULL)
@@ -800,7 +800,7 @@ op_delete(oparg_T *oap)
            // Thus the number of characters may increase!
            n = bd.textlen - bd.startspaces - bd.endspaces;
            oldp = ml_get(lnum);
-           newp = alloc(STRLEN(oldp) + 1 - n);
+           newp = alloc(ml_get_len(lnum) + 1 - n);
            if (newp == NULL)
                continue;
            // copy up to deleted part
@@ -920,8 +920,7 @@ op_delete(oparg_T *oap)
            {
                // fix up things for virtualedit-delete:
                // break the tabs which are going to get in our way
-               char_u          *curline = ml_get_curline();
-               int             len = (int)STRLEN(curline);
+               int             len = ml_get_curline_len();
 
                if (oap->end.coladd != 0
                        && (int)oap->end.col >= len - 1
@@ -1116,7 +1115,7 @@ op_replace(oparg_T *oap, int c)
            n += numc - bd.textlen;
 
            oldp = ml_get_curline();
-           oldlen = STRLEN(oldp);
+           oldlen = ml_get_curline_len();
            newp = alloc(oldlen + 1 + n);
            if (newp == NULL)
                continue;
@@ -1174,7 +1173,7 @@ op_replace(oparg_T *oap, int c)
        {
            oap->start.col = 0;
            curwin->w_cursor.col = 0;
-           oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+           oap->end.col = ml_get_len(oap->end.lnum);
            if (oap->end.col)
                --oap->end.col;
        }
@@ -1320,7 +1319,7 @@ op_tilde(oparg_T *oap)
        {
            oap->start.col = 0;
            pos.col = 0;
-           oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+           oap->end.col = ml_get_len(oap->end.lnum);
            if (oap->end.col)
                --oap->end.col;
        }
@@ -1334,8 +1333,8 @@ op_tilde(oparg_T *oap)
            for (;;)
            {
                did_change |= swapchars(oap->op_type, &pos,
-                               pos.lnum == oap->end.lnum ? oap->end.col + 1:
-                                          (int)STRLEN(ml_get_pos(&pos)));
+                       pos.lnum == oap->end.lnum ? oap->end.col + 1
+                                                 : ml_get_pos_len(&pos));
                if (LTOREQ_POS(oap->end, pos) || inc(&pos) == -1)
                    break;
            }
@@ -1353,7 +1352,7 @@ op_tilde(oparg_T *oap)
                while (pos.lnum < oap->end.lnum)
                {
                    ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
-                   count = (int)STRLEN(ptr) - pos.col;
+                   count = ml_get_buf_len(curbuf, pos.lnum) - pos.col;
                    netbeans_removed(curbuf, pos.lnum, pos.col, (long)count);
                    // get the line again, it may have been flushed
                    ptr = ml_get_buf(curbuf, pos.lnum, FALSE);
@@ -1542,10 +1541,13 @@ op_insert(oparg_T *oap, long count1)
        ind_pre_col = (colnr_T)getwhitecols_curline();
        ind_pre_vcol = get_indent();
        firstline = ml_get(oap->start.lnum) + bd.textcol;
+       pre_textlen = ml_get_len(oap->start.lnum) - bd.textcol;
 
        if (oap->op_type == OP_APPEND)
+       {
            firstline += bd.textlen;
-       pre_textlen = (long)STRLEN(firstline);
+           pre_textlen -= bd.textlen;
+       }
     }
 
     if (oap->op_type == OP_APPEND)
@@ -1686,7 +1688,7 @@ op_insert(oparg_T *oap, long count1)
         * copy of the required string.
         */
        firstline = ml_get(oap->start.lnum);
-       len = STRLEN(firstline);
+       len = ml_get_len(oap->start.lnum);
        add = bd.textcol;
        if (oap->op_type == OP_APPEND)
        {
@@ -1706,11 +1708,10 @@ op_insert(oparg_T *oap, long count1)
            }
        }
        if ((size_t)add > len)
-           firstline += len;  // short line, point to the NUL
-       else
-           firstline += add;
-       if (pre_textlen >= 0 && (ins_len =
-                          (long)STRLEN(firstline) - pre_textlen - offset) > 0)
+           add = len;  // short line, point to the NUL
+       firstline += add;
+       len -= add;
+       if (pre_textlen >= 0 && (ins_len = len - pre_textlen - offset) > 0)
        {
            ins_text = vim_strnsave(firstline, ins_len);
            if (ins_text != NULL)
@@ -1778,7 +1779,7 @@ op_change(oparg_T *oap)
                                                    || gchar_cursor() == NUL))
            coladvance_force(getviscol());
        firstline = ml_get(oap->start.lnum);
-       pre_textlen = (long)STRLEN(firstline);
+       pre_textlen = ml_get_len(oap->start.lnum);
        pre_indent = (long)getwhitecols(firstline);
        bd.textcol = curwin->w_cursor.col;
     }
@@ -1812,7 +1813,7 @@ op_change(oparg_T *oap)
            bd.textcol += new_indent - pre_indent;
        }
 
-       ins_len = (long)STRLEN(firstline) - pre_textlen;
+       ins_len = ml_get_len(oap->start.lnum) - pre_textlen;
        if (ins_len > 0)
        {
            // Subsequent calls to ml_get() flush the firstline data - take a
@@ -1838,7 +1839,8 @@ op_change(oparg_T *oap)
                        else
                            vpos.coladd = 0;
                        oldp = ml_get(linenr);
-                       newp = alloc(STRLEN(oldp) + 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
@@ -2491,7 +2493,7 @@ charwise_block_prep(
        }
     }
     if (endcol == MAXCOL)
-       endcol = (colnr_T)STRLEN(p);
+       endcol = ml_get_len(lnum);
     if (startcol > endcol || is_oneChar)
        bdp->textlen = 0;
     else
@@ -2565,13 +2567,13 @@ op_addsub(
            {
                curwin->w_cursor.col = 0;
                pos.col = 0;
-               length = (colnr_T)STRLEN(ml_get(pos.lnum));
+               length = ml_get_len(pos.lnum);
            }
            else // oap->motion_type == MCHAR
            {
                if (pos.lnum == oap->start.lnum && !oap->inclusive)
                    dec(&(oap->end));
-               length = (colnr_T)STRLEN(ml_get(pos.lnum));
+               length = ml_get_len(pos.lnum);
                pos.col = 0;
                if (pos.lnum == oap->start.lnum)
                {
@@ -2580,7 +2582,7 @@ op_addsub(
                }
                if (pos.lnum == oap->end.lnum)
                {
-                   length = (int)STRLEN(ml_get(oap->end.lnum));
+                   length = ml_get_len(oap->end.lnum);
                    if (oap->end.col >= length)
                        oap->end.col = length - 1;
                    length = oap->end.col - pos.col + 1;
@@ -3048,14 +3050,12 @@ do_addsub(
        // del_char() will also mark line needing displaying
        if (todel > 0)
        {
-           int bytes_after = (int)STRLEN(ml_get_curline())
-                                                       - curwin->w_cursor.col;
+           int bytes_after = ml_get_curline_len() - curwin->w_cursor.col;
 
            // Delete the one character before the insert.
            curwin->w_cursor = save_pos;
            (void)del_char(FALSE);
-           curwin->w_cursor.col = (colnr_T)(STRLEN(ml_get_curline())
-                                                               - bytes_after);
+           curwin->w_cursor.col = ml_get_curline_len() - bytes_after;
            --todel;
        }
        while (todel-- > 0)
@@ -3361,7 +3361,7 @@ cursor_pos_info(dict_T *dict)
                validate_virtcol();
                col_print(buf1, sizeof(buf1), (int)curwin->w_cursor.col + 1,
                        (int)curwin->w_virtcol + 1);
-               col_print(buf2, sizeof(buf2), (int)STRLEN(p),
+               col_print(buf2, sizeof(buf2), ml_get_curline_len(),
                                                           linetabsize_str(p));
 
                if (char_count_cursor == byte_count_cursor
@@ -3858,13 +3858,12 @@ do_pending_operator(cmdarg_T *cap, int old_col, int 
gui_yank)
                if (LT_POS(VIsual, curwin->w_cursor))
                {
                    VIsual.col = 0;
-                   curwin->w_cursor.col =
-                              (colnr_T)STRLEN(ml_get(curwin->w_cursor.lnum));
+                   curwin->w_cursor.col = ml_get_len(curwin->w_cursor.lnum);
                }
                else
                {
                    curwin->w_cursor.col = 0;
-                   VIsual.col = (colnr_T)STRLEN(ml_get(VIsual.lnum));
+                   VIsual.col = ml_get_len(VIsual.lnum);
                }
                VIsual_mode = 'v';
            }
@@ -3895,7 +3894,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int 
gui_yank)
                                                  || oap->motion_type == MLINE)
                        && hasFolding(curwin->w_cursor.lnum, NULL,
                                                      &curwin->w_cursor.lnum))
-                   curwin->w_cursor.col = (colnr_T)STRLEN(ml_get_curline());
+                   curwin->w_cursor.col = ml_get_curline_len();
            }
 #endif
            oap->end = curwin->w_cursor;
@@ -3916,7 +3915,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int 
gui_yank)
                                                                        NULL))
                    curwin->w_cursor.col = 0;
                if (hasFolding(oap->start.lnum, NULL, &oap->start.lnum))
-                   oap->start.col = (colnr_T)STRLEN(ml_get(oap->start.lnum));
+                   oap->start.col = ml_get_len(oap->start.lnum);
            }
 #endif
            oap->end = oap->start;
@@ -4126,7 +4125,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int 
gui_yank)
                oap->motion_type = MLINE;
            else
            {
-               oap->end.col = (colnr_T)STRLEN(ml_get(oap->end.lnum));
+               oap->end.col = ml_get_len(oap->end.lnum);
                if (oap->end.col)
                {
                    --oap->end.col;
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index eb21a7eec..c5d9b5d8d 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -20,6 +20,7 @@ char_u *ml_get_pos(pos_T *pos);
 char_u *ml_get_curline(void);
 char_u *ml_get_cursor(void);
 colnr_T ml_get_len(linenr_T lnum);
+colnr_T ml_get_pos_len(pos_T *pos);
 colnr_T ml_get_curline_len(void);
 colnr_T ml_get_cursor_len(void);
 colnr_T ml_get_buf_len(buf_T *buf, linenr_T lnum);
diff --git a/src/quickfix.c b/src/quickfix.c
index 614980761..006c1346f 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -780,9 +780,9 @@ qf_get_next_buf_line(qfstate_T *state)
        return QF_END_OF_INPUT;
 
     p_buf = ml_get_buf(state->buf, state->buflnum, FALSE);
+    len = ml_get_buf_len(state->buf, state->buflnum);
     state->buflnum += 1;
 
-    len = (int)STRLEN(p_buf);
     if (len > IOSIZE - 2)
     {
        state->linebuf = qf_grow_linebuf(state, len);
@@ -6196,13 +6196,14 @@ vgr_match_buflines(
                    break;
                col = regmatch->endpos[0].col
                    + (col == regmatch->endpos[0].col);
-               if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE)))
+               if (col > ml_get_buf_len(buf, lnum))
                    break;
            }
        }
        else
        {
            char_u  *str = ml_get_buf(buf, lnum, FALSE);
+           int     line_len = ml_get_buf_len(buf, lnum);
            int     score;
            int_u   matches[MAX_FUZZY_MATCHES];
            int_u   sz = ARRAY_LENGTH(matches);
@@ -6241,7 +6242,7 @@ vgr_match_buflines(
                if ((flags & VGR_GLOBAL) == 0)
                    break;
                col = matches[pat_len - 1] + col + 1;
-               if (col > (colnr_T)STRLEN(str))
+               if (col > line_len)
                    break;
            }
        }
diff --git a/src/register.c b/src/register.c
index 98015e05b..47ed21846 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1793,7 +1793,7 @@ do_put(
            }
            // get the old line and advance to the position to insert at
            oldp = ml_get_curline();
-           oldlen = (int)STRLEN(oldp);
+           oldlen = ml_get_curline_len();
            init_chartabsize_arg(&cts, curwin, curwin->w_cursor.lnum, 0,
                                                                  oldp, oldp);
 
@@ -1924,7 +1924,7 @@ do_put(
            curwin->w_cursor.col++;
 
            // in Insert mode we might be after the NUL, correct for that
-           len = (colnr_T)STRLEN(ml_get_curline());
+           len = ml_get_curline_len();
            if (curwin->w_cursor.col > len)
                curwin->w_cursor.col = len;
        }
@@ -2008,7 +2008,7 @@ do_put(
                totlen = count * yanklen;
                do {
                    oldp = ml_get(lnum);
-                   oldlen = (int)STRLEN(oldp);
+                   oldlen = ml_get_len(lnum);
                    if (lnum > start_lnum)
                    {
                        pos_T   pos;
@@ -2088,7 +2088,7 @@ do_put(
                    lnum = new_cursor.lnum;
                    ptr = ml_get(lnum) + col;
                    totlen = (int)STRLEN(y_array[y_size - 1]);
-                   newp = alloc(STRLEN(ptr) + totlen + 1);
+                   newp = alloc(ml_get_len(lnum) - col + totlen + 1);
                    if (newp == NULL)
                        goto error;
                    STRCPY(newp, y_array[y_size - 1]);
@@ -2129,7 +2129,7 @@ do_put(
                        curwin->w_cursor.lnum = lnum;
                        ptr = ml_get(lnum);
                        if (cnt == count && i == y_size - 1)
-                           lendiff = (int)STRLEN(ptr);
+                           lendiff = ml_get_len(lnum);
                        if (*ptr == '#' && preprocs_left())
                            indent = 0;     // Leave # lines at start
                        else
@@ -2147,7 +2147,7 @@ do_put(
                        curwin->w_cursor = old_pos;
                        // remember how many chars were removed
                        if (cnt == count && i == y_size - 1)
-                           lendiff -= (int)STRLEN(ml_get(lnum));
+                           lendiff -= ml_get_len(lnum);
                    }
                }
                if (cnt == 1)
@@ -2239,7 +2239,7 @@ error:
     curwin->w_set_curswant = TRUE;
 
     // Make sure the cursor is not after the NUL.
-    int len = (int)STRLEN(ml_get_curline());
+    int len = ml_get_curline_len();
     if (curwin->w_cursor.col > len)
     {
        if (cur_ve_flags == VE_ALL)
diff --git a/src/search.c b/src/search.c
index 83aaf0ac3..166ef4a58 100644
--- a/src/search.c
+++ b/src/search.c
@@ -660,7 +660,7 @@ searchit(
                                                    && pos->col < MAXCOL - 2)
        {
            ptr = ml_get_buf(buf, pos->lnum, FALSE);
-           if ((int)STRLEN(ptr) <= pos->col)
+           if (ml_get_buf_len(buf, pos->lnum) <= pos->col)
                start_char_len = 1;
            else
                start_char_len = (*mb_ptr2len)(ptr + pos->col);
@@ -966,8 +966,7 @@ searchit(
                            if (pos->lnum > 1)  // just in case
                            {
                                --pos->lnum;
-                               pos->col = (colnr_T)STRLEN(ml_get_buf(buf,
-                                                          pos->lnum, FALSE));
+                               pos->col = ml_get_buf_len(buf, pos->lnum);
                            }
                        }
                        else
@@ -1102,7 +1101,7 @@ searchit(
     if (pos->lnum > buf->b_ml.ml_line_count)
     {
        pos->lnum = buf->b_ml.ml_line_count;
-       pos->col = (int)STRLEN(ml_get_buf(buf, pos->lnum, FALSE));
+       pos->col = ml_get_buf_len(buf, pos->lnum);
        if (pos->col > 0)
            --pos->col;
     }
@@ -1772,7 +1771,7 @@ searchc(cmdarg_T *cap, int t_cmd)
 
     p = ml_get_curline();
     col = curwin->w_cursor.col;
-    len = (int)STRLEN(p);
+    len = ml_get_curline_len();
 
     while (count--)
     {
@@ -2315,7 +2314,7 @@ findmatchlimit(
                    break;
 
                linep = ml_get(pos.lnum);
-               pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL
+               pos.col = ml_get_len(pos.lnum); // pos.col on trailing NUL
                do_quotes = -1;
                line_breakcheck();
 
@@ -2492,7 +2491,7 @@ findmatchlimit(
                if (pos.lnum > 1)
                {
                    ptr = ml_get(pos.lnum - 1);
-                   if (*ptr && *(ptr + STRLEN(ptr) - 1) == '\')
+                   if (*ptr && *(ptr + ml_get_len(pos.lnum - 1) - 1) == '\')
                    {
                        do_quotes = 1;
                        if (start_in_quotes == MAYBE)
@@ -2986,8 +2985,7 @@ current_search(
                // try again from end of buffer
                // searching backwards, so set pos to last line and col
                pos.lnum = curwin->w_buffer->b_ml.ml_line_count;
-               pos.col  = (colnr_T)STRLEN(
-                               ml_get(curwin->w_buffer->b_ml.ml_line_count));
+               pos.col  = ml_get_len(curwin->w_buffer->b_ml.ml_line_count);
            }
        }
     }
diff --git a/src/spell.c b/src/spell.c
index da8ece036..43c521dde 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -1384,7 +1384,7 @@ spell_move_to(
 
        line = ml_get_buf(wp->w_buffer, lnum, FALSE);
 
-       len = (int)STRLEN(line);
+       len = ml_get_buf_len(wp->w_buffer, lnum);
        if (buflen < len + MAXWLEN + 2)
        {
            vim_free(buf);
@@ -2988,7 +2988,7 @@ ex_spellrepall(exarg_T *eap UNUSED)
        if (addlen <= 0 || STRNCMP(line + curwin->w_cursor.col,
                                                   repl_to, repl_to_len) != 0)
        {
-           p = alloc(STRLEN(line) + addlen + 1);
+           p = alloc(ml_get_curline_len() + addlen + 1);
            if (p == NULL)
                break;
            mch_memmove(p, line, curwin->w_cursor.col);
diff --git a/src/spellfile.c b/src/spellfile.c
index 24df042b7..51261abfb 100644
--- a/src/spellfile.c
+++ b/src/spellfile.c
@@ -5877,7 +5877,7 @@ sug_write(spellinfo_T *spin, char_u *fname)
     {
        // <sugline>: <sugnr> ... NUL
        line = ml_get_buf(spin->si_spellbuf, lnum, FALSE);
-       len = (int)STRLEN(line) + 1;
+       len = ml_get_buf_len(spin->si_spellbuf, lnum) + 1;
        if (fwrite(line, (size_t)len, (size_t)1, fd) == 0)
        {
            emsg(_(e_error_while_writing));
diff --git a/src/spellsuggest.c b/src/spellsuggest.c
index 82499c0d1..ded04af1a 100644
--- a/src/spellsuggest.c
+++ b/src/spellsuggest.c
@@ -509,8 +509,8 @@ spell_suggest(int count)
        end_visual_mode();
        // make sure we don't include the NUL at the end of the line
        line = ml_get_curline();
-       if (badlen > (int)STRLEN(line) - (int)curwin->w_cursor.col)
-           badlen = (int)STRLEN(line) - (int)curwin->w_cursor.col;
+       if (badlen > ml_get_curline_len() - (int)curwin->w_cursor.col)
+           badlen = ml_get_curline_len() - (int)curwin->w_cursor.col;
     }
     // Find the start of the badly spelled word.
     else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
@@ -543,7 +543,7 @@ spell_suggest(int count)
                                                        curwin->w_cursor.col);
 
     // Make a copy of current line since autocommands may free the line.
-    line = vim_strsave(ml_get_curline());
+    line = vim_strnsave(ml_get_curline(), ml_get_curline_len());
     if (line == NULL)
        goto skip;
 
diff --git a/src/syntax.c b/src/syntax.c
index 4e3595690..48e715201 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -593,7 +593,6 @@ syn_sync(
     int                had_sync_point;
     stateitem_T        *cur_si;
     synpat_T   *spp;
-    char_u     *line;
     int                found_flags = 0;
     int                found_match_idx = 0;
     linenr_T   found_current_lnum = 0;
@@ -651,8 +650,9 @@ syn_sync(
         */
        for ( ; start_lnum > 1; --start_lnum)
        {
-           line = ml_get(start_lnum - 1);
-           if (*line == NUL || *(line + STRLEN(line) - 1) != '\')
+           char_u      *l = ml_get(start_lnum - 1);
+
+           if (*l == NUL || *(l + ml_get_len(start_lnum - 1) - 1) != '\')
                break;
        }
        current_lnum = start_lnum;
@@ -2775,7 +2775,6 @@ find_endpos(
     regmmatch_T        regmatch;
     regmmatch_T        best_regmatch;      // startpos/endpos of best match
     lpos_T     pos;
-    char_u     *line;
     int                had_match = FALSE;
     char_u     buf_chartab[32];  // chartab array for syn option iskyeyword
 
@@ -2899,8 +2898,7 @@ find_endpos(
                if (pos.lnum > startpos->lnum)
                    break;
 
-               line = ml_get_buf(syn_buf, startpos->lnum, FALSE);
-               line_len = (int)STRLEN(line);
+               line_len = ml_get_buf_len(syn_buf, startpos->lnum);
 
                // take care of an empty match or negative offset
                if (pos.col <= matchcol)
@@ -3101,7 +3099,7 @@ syn_add_start_off(
     {
        // a "
" at the end of the pattern may take us below the last line
        result->lnum = syn_buf->b_ml.ml_line_count;
-       col = (int)STRLEN(ml_get_buf(syn_buf, result->lnum, FALSE));
+       col = ml_get_buf_len(syn_buf, result->lnum);
     }
     if (off != 0)
     {
diff --git a/src/textformat.c b/src/textformat.c
index 500e8895c..14acc53cd 100644
--- a/src/textformat.c
+++ b/src/textformat.c
@@ -455,7 +455,7 @@ internal_format(
            // Check if cursor is not past the NUL off the line, cindent
            // may have added or removed indent.
            curwin->w_cursor.col += startcol;
-           len = (colnr_T)STRLEN(ml_get_curline());
+           len = ml_get_curline_len();
            if (curwin->w_cursor.col > len)
                curwin->w_cursor.col = len;
        }
@@ -531,9 +531,7 @@ ends_in_white(linenr_T lnum)
 
     if (*s == NUL)
        return FALSE;
-    // Don't use STRLEN() inside VIM_ISWHITE(), SAS/C complains: "macro
-    // invocation may call function multiple times".
-    l = STRLEN(s) - 1;
+    l = ml_get_len(lnum) - 1;
     return VIM_ISWHITE(s[l]);
 }
 
@@ -573,7 +571,7 @@ same_leader(
                return FALSE;
            if (*p == COM_START)
            {
-               int line_len = (int)STRLEN(ml_get(lnum));
+               int line_len = ml_get_len(lnum);
                if (line_len <= leader1_len)
                    return FALSE;
                if (leader2_flags == NULL || leader2_len == 0)
@@ -684,7 +682,7 @@ auto_format(
     // in 'formatoptions' and there is a single character before the cursor.
     // Otherwise the line would be broken and when typing another non-white
     // next they are not joined back together.
-    wasatend = (pos.col == (colnr_T)STRLEN(old));
+    wasatend = (pos.col == ml_get_curline_len());
     if (*old != NUL && !trailblank && wasatend)
     {
        dec_cursor();
@@ -740,7 +738,7 @@ auto_format(
     if (!wasatend && has_format_option(FO_WHITE_PAR))
     {
        new = ml_get_curline();
-       len = (colnr_T)STRLEN(new);
+       len = ml_get_curline_len();
        if (curwin->w_cursor.col == len)
        {
            pnew = vim_strnsave(new, len + 2);
@@ -1217,7 +1215,7 @@ format_lines(
                }
                first_par_line = FALSE;
                // If the line is getting long, format it next time
-               if (STRLEN(ml_get_curline()) > (size_t)max_len)
+               if (ml_get_curline_len() > max_len)
                    force_format = TRUE;
                else
                    force_format = FALSE;
diff --git a/src/textobject.c b/src/textobject.c
index 015b33bbf..1890d7c83 100644
--- a/src/textobject.c
+++ b/src/textobject.c
@@ -232,7 +232,7 @@ findpar(
 
        // Put the cursor on the last character in the last line and make the
        // motion inclusive.
-       if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0)
+       if ((curwin->w_cursor.col = ml_get_len(curr)) != 0)
        {
            --curwin->w_cursor.col;
            curwin->w_cursor.col -=
diff --git a/src/textprop.c b/src/textprop.c
index cd07844f1..a97657018 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -637,7 +637,7 @@ get_text_props(buf_T *buf, linenr_T lnum, char_u **props, 
int will_change)
 
     // Fetch the line to get the ml_line_len field updated.
     text = ml_get_buf(buf, lnum, will_change);
-    textlen = STRLEN(text) + 1;
+    textlen = ml_get_buf_len(buf, lnum) + 1;
     proplen = buf->b_ml.ml_line_len - textlen;
     if (proplen == 0)
        return 0;
@@ -864,7 +864,7 @@ set_text_props(linenr_T lnum, char_u *props, int len)
     int            textlen;
 
     text = ml_get(lnum);
-    textlen = (int)STRLEN(text) + 1;
+    textlen = ml_get_len(lnum) + 1;
     newtext = alloc(textlen + len);
     if (newtext == NULL)
        return;
@@ -1091,7 +1091,7 @@ f_prop_clear(typval_T *argvars, typval_T *rettv UNUSED)
        if (lnum > buf->b_ml.ml_line_count)
            break;
        text = ml_get_buf(buf, lnum, FALSE);
-       len = STRLEN(text) + 1;
+       len = ml_get_buf_len(buf, lnum) + 1;
        if ((size_t)buf->b_ml.ml_line_len > len)
        {
            did_clear = TRUE;
@@ -1221,7 +1221,7 @@ f_prop_find(typval_T *argvars, typval_T *rettv)
     while (1)
     {
        char_u  *text = ml_get_buf(buf, lnum, FALSE);
-       size_t  textlen = STRLEN(text) + 1;
+       size_t  textlen = ml_get_buf_len(buf, lnum) + 1;
        int     count = (int)((buf->b_ml.ml_line_len - textlen)
                                                         / sizeof(textprop_T));
        int         i;
@@ -1342,7 +1342,7 @@ get_props_in_line(
        int             add_lnum)
 {
     char_u     *text = ml_get_buf(buf, lnum, FALSE);
-    size_t     textlen = STRLEN(text) + 1;
+    size_t     textlen = ml_get_buf_len(buf, lnum) + 1;
     int                count;
     int                i;
     textprop_T prop;
@@ -1675,13 +1675,11 @@ f_prop_remove(typval_T *argvars, typval_T *rettv)
        end = buf->b_ml.ml_line_count;
     for (lnum = start; lnum <= end; ++lnum)
     {
-       char_u *text;
        size_t len;
 
        if (lnum > buf->b_ml.ml_line_count)
            break;
-       text = ml_get_buf(buf, lnum, FALSE);
-       len = STRLEN(text) + 1;
+       len = ml_get_buf_len(buf, lnum) + 1;
        if ((size_t)buf->b_ml.ml_line_len > len)
        {
            static textprop_T   textprop;  // static because of alignment
diff --git a/src/version.c b/src/version.c
index 848536238..4e8e9dcce 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 */
+/**/
+    172,
 /**/
     171,
 /**/

-- 
-- 
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/E1rk9EC-00FXea-VZ%40256bit.org.

Raspunde prin e-mail lui