]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0997: too many strlen() calls in drawscreen.c v9.1.0997
authorJohn Marriott <basilisk@internode.on.net>
Wed, 8 Jan 2025 19:10:59 +0000 (20:10 +0100)
committerChristian Brabandt <cb@256bit.org>
Wed, 8 Jan 2025 19:10:59 +0000 (20:10 +0100)
Problem:  too many strlen() calls in drawscreen.c
Solution: refactor drawscreen.c and remove calls to strlen(),
          make get_keymap_str() (in screen.c) return string length
          instead of TRUE/FALSE (John Marriott).

Signed-off-by: John Marriott <basilisk@internode.on.net>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/buffer.c
src/drawscreen.c
src/proto/buffer.pro
src/screen.c
src/version.c

index 147d20dc78f0ffdcb34ab5a7e155d8b26e3a1a50..a925552199a513e626b27b3b1924f45cb0d660e6 100644 (file)
@@ -3914,7 +3914,7 @@ fileinfo(
                n);
        validate_virtcol();
        len = STRLEN(buffer);
-       col_print((char_u *)buffer + len, IOSIZE - len,
+       (void)col_print((char_u *)buffer + len, IOSIZE - len,
                   (int)curwin->w_cursor.col + 1, (int)curwin->w_virtcol + 1);
     }
 
@@ -3946,7 +3946,7 @@ fileinfo(
     vim_free(buffer);
 }
 
-    void
+    int
 col_print(
     char_u  *buf,
     size_t  buflen,
@@ -3954,9 +3954,9 @@ col_print(
     int            vcol)
 {
     if (col == vcol)
-       vim_snprintf((char *)buf, buflen, "%d", col);
-    else
-       vim_snprintf((char *)buf, buflen, "%d-%d", col, vcol);
+       return vim_snprintf((char *)buf, buflen, "%d", col);
+
+    return vim_snprintf((char *)buf, buflen, "%d-%d", col, vcol);
 }
 
 static char_u *lasttitle = NULL;
@@ -4820,7 +4820,7 @@ build_stl_str_hl(
 
        case STL_ALTPERCENT:
            str = buf_tmp;
-           get_rel_pos(wp, str, TMPLEN);
+           (void)get_rel_pos(wp, str, TMPLEN);
            break;
 
        case STL_SHOWCMD:
@@ -4837,7 +4837,7 @@ build_stl_str_hl(
 
        case STL_KEYMAP:
            fillable = FALSE;
-           if (get_keymap_str(wp, (char_u *)"<%s>", buf_tmp, TMPLEN))
+           if (get_keymap_str(wp, (char_u *)"<%s>", buf_tmp, TMPLEN) > 0)
                str = buf_tmp;
            break;
        case STL_PAGENUM:
@@ -5271,7 +5271,7 @@ build_stl_str_hl(
  * Get relative cursor position in window into "buf[buflen]", in the localized
  * percentage form like %99, 99%; using "Top", "Bot" or "All" when appropriate.
  */
-    void
+    int
 get_rel_pos(
     win_T      *wp,
     char_u     *buf,
@@ -5279,9 +5279,10 @@ get_rel_pos(
 {
     long       above; // number of lines above window
     long       below; // number of lines below window
+    int                len;
 
     if (buflen < 3) // need at least 3 chars for writing
-       return;
+       return 0;
     above = wp->w_topline - 1;
 #ifdef FEAT_DIFF
     above += diff_check_fill(wp, wp->w_topline) - wp->w_topfill;
@@ -5292,28 +5293,27 @@ get_rel_pos(
 #endif
     below = wp->w_buffer->b_ml.ml_line_count - wp->w_botline + 1;
     if (below <= 0)
-       vim_strncpy(buf, (char_u *)(above == 0 ? _("All") : _("Bot")),
-                   (size_t)(buflen - 1));
+       len = vim_snprintf((char *)buf, buflen, "%s", (above == 0) ? _("All") : _("Bot"));
     else if (above <= 0)
-       vim_strncpy(buf, (char_u *)_("Top"), (size_t)(buflen - 1));
+       len = vim_snprintf((char *)buf, buflen, "%s", _("Top"));
     else
     {
        int perc = (above > 1000000L)
-                       ?  (int)(above / ((above + below) / 100L))
-                       :  (int)(above * 100L / (above + below));
+                   ?  (int)(above / ((above + below) / 100L))
+                   :  (int)(above * 100L / (above + below));
 
-       char *p = (char *)buf;
-       size_t l = buflen;
-       if (perc < 10)
-       {
-           // prepend one space
-           buf[0] = ' ';
-           ++p;
-           --l;
-       }
        // localized percentage value
-       vim_snprintf(p, l, _("%d%%"), perc);
+       len = vim_snprintf((char *)buf, buflen, _("%s%d%%"), (perc < 10) ? " " : "", perc);
     }
+    if (len < 0)
+    {
+       buf[0] = NUL;
+       len = 0;
+    }
+    else if (len > buflen - 1)
+       len = buflen - 1;
+
+    return len;
 }
 
 /*
index 778cda4d4f4f59a4dcd30e4598d6a42843c6726a..36034cc9dfc86b19092cad5c3eb8e50f2666ef17 100644 (file)
@@ -425,11 +425,8 @@ statusline_row(win_T *wp)
 win_redr_status(win_T *wp, int ignore_pum UNUSED)
 {
     int                row;
-    char_u     *p;
-    int                len;
     int                fillchar;
     int                attr;
-    int                this_ru_col;
     static int  busy = FALSE;
 
     // It's possible to get here recursively when 'statusline' (indirectly)
@@ -463,11 +460,17 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
 #endif
     else
     {
+       char_u  *p;
+       int     plen;
+       int     NameBufflen;
+       int     this_ru_col;
+       int     n;                      // scratch value
+
        fillchar = fillchar_status(&attr, wp);
 
        get_trans_bufname(wp->w_buffer);
        p = NameBuff;
-       len = (int)STRLEN(p);
+       plen = (int)STRLEN(p);
 
        if ((bt_help(wp->w_buffer)
 #ifdef FEAT_QUICKFIX
@@ -475,74 +478,61 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
 #endif
                    || bufIsChanged(wp->w_buffer)
                    || wp->w_buffer->b_p_ro)
-               && len < MAXPATHL - 1)
-           *(p + len++) = ' ';
+               && plen < MAXPATHL - 1)
+           *(p + plen++) = ' ';
        if (bt_help(wp->w_buffer))
-       {
-           vim_snprintf((char *)p + len, MAXPATHL - len, "%s", _("[Help]"));
-           len += (int)STRLEN(p + len);
-       }
+           plen += vim_snprintf((char *)p + plen, MAXPATHL - plen, "%s", _("[Help]"));
 #ifdef FEAT_QUICKFIX
        if (wp->w_p_pvw)
-       {
-           vim_snprintf((char *)p + len, MAXPATHL - len, "%s", _("[Preview]"));
-           len += (int)STRLEN(p + len);
-       }
+           plen += vim_snprintf((char *)p + plen, MAXPATHL - plen, "%s", _("[Preview]"));
 #endif
        if (bufIsChanged(wp->w_buffer) && !bt_terminal(wp->w_buffer))
-       {
-           vim_snprintf((char *)p + len, MAXPATHL - len, "%s", "[+]");
-           len += (int)STRLEN(p + len);
-       }
+           plen += vim_snprintf((char *)p + plen, MAXPATHL - plen, "%s", "[+]");
        if (wp->w_buffer->b_p_ro)
-       {
-           vim_snprintf((char *)p + len, MAXPATHL - len, "%s", _("[RO]"));
-           len += (int)STRLEN(p + len);
-       }
+           plen += vim_snprintf((char *)p + plen, MAXPATHL - plen, "%s", _("[RO]"));
 
        this_ru_col = ru_col - (Columns - wp->w_width);
-       if (this_ru_col < (wp->w_width + 1) / 2)
-           this_ru_col = (wp->w_width + 1) / 2;
+       n = (wp->w_width + 1) / 2;
+       if (this_ru_col < n)
+           this_ru_col = n;
        if (this_ru_col <= 1)
        {
            p = (char_u *)"<";          // No room for file name!
-           len = 1;
+           plen = 1;
        }
        else if (has_mbyte)
        {
-           int clen = 0, i;
+           int i;
 
            // Count total number of display cells.
-           clen = mb_string2cells(p, -1);
+           plen = mb_string2cells(p, -1);
 
            // Find first character that will fit.
            // Going from start to end is much faster for DBCS.
-           for (i = 0; p[i] != NUL && clen >= this_ru_col - 1;
+           for (i = 0; p[i] != NUL && plen >= this_ru_col - 1;
                    i += (*mb_ptr2len)(p + i))
-               clen -= (*mb_ptr2cells)(p + i);
-           len = clen;
+               plen -= (*mb_ptr2cells)(p + i);
            if (i > 0)
            {
                p = p + i - 1;
                *p = '<';
-               ++len;
+               ++plen;
            }
-
        }
-       else if (len > this_ru_col - 1)
+       else if (plen > this_ru_col - 1)
        {
-           p += len - (this_ru_col - 1);
+           p += plen - (this_ru_col - 1);
            *p = '<';
-           len = this_ru_col - 1;
+           plen = this_ru_col - 1;
        }
 
        screen_puts(p, row, wp->w_wincol, attr);
-       screen_fill(row, row + 1, len + wp->w_wincol,
+       screen_fill(row, row + 1, plen + wp->w_wincol,
                        this_ru_col + wp->w_wincol, fillchar, fillchar, attr);
 
-       if (get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL)
-               && (this_ru_col - len) > (int)(STRLEN(NameBuff) + 1))
-           screen_puts(NameBuff, row, (int)(this_ru_col - STRLEN(NameBuff)
+       if ((NameBufflen = get_keymap_str(wp, (char_u *)"<%s>", NameBuff, MAXPATHL)) > 0
+               && (this_ru_col - plen) > (NameBufflen + 1))
+           screen_puts(NameBuff, row, (int)(this_ru_col - NameBufflen
                                                   - 1 + wp->w_wincol), attr);
 
        win_redr_ruler(wp, TRUE, ignore_pum);
@@ -550,7 +540,8 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
        // Draw the 'showcmd' information if 'showcmdloc' == "statusline".
        if (p_sc && *p_sloc == 's')
        {
-           int width = MIN(10, this_ru_col - len - 2);
+           n = this_ru_col - plen - 2;             // perform the calculation here so we only do it once
+           int width = MIN(10, n);
 
            if (width > 0)
                screen_puts_len(showcmd_buf, width, row,
@@ -631,19 +622,7 @@ showruler(int always)
     void
 win_redr_ruler(win_T *wp, int always, int ignore_pum)
 {
-#define RULER_BUF_LEN 70
-    char_u     buffer[RULER_BUF_LEN];
-    int                row;
-    int                fillchar;
-    int                attr;
-    int                empty_line = FALSE;
-    colnr_T    virtcol;
-    int                i;
-    size_t     len;
-    int                o;
-    int                this_ru_col;
-    int                off = 0;
-    int                width;
+    int        empty_line = FALSE;
 
     // If 'ruler' off don't do anything
     if (!p_ru)
@@ -661,6 +640,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
     if (wp == lastwin && lastwin->w_status_height == 0)
        if (edit_submode != NULL)
            return;
+
     // Don't draw the ruler when the popup menu is visible, it may overlap.
     // Except when the popup menu will be redrawn anyway.
     if (!ignore_pum && pum_visible())
@@ -698,6 +678,21 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
 #endif
            || empty_line != wp->w_ru_empty)
     {
+       int     row;
+       int     fillchar;
+       int     attr;
+       int     off;
+       int     width;
+       colnr_T virtcol;
+#define RULER_BUF_LEN 70
+       char_u  buffer[RULER_BUF_LEN];
+       int     bufferlen;
+       char_u  rel_pos[RULER_BUF_LEN];
+       int     rel_poslen;
+       int     this_ru_col;
+       int     n1;                         // scratch value
+       int     n2;                         // scratch value
+
        cursor_off();
        if (wp->w_status_height)
        {
@@ -724,16 +719,11 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
            wp->w_p_list = TRUE;
        }
 
-       /*
-        * Some sprintfs return the length, some return a pointer.
-        * To avoid portability problems we use strlen() here.
-        */
-       vim_snprintf((char *)buffer, RULER_BUF_LEN, "%ld,",
+       bufferlen = vim_snprintf((char *)buffer, RULER_BUF_LEN, "%ld,",
                (wp->w_buffer->b_ml.ml_flags & ML_EMPTY)
                    ? 0L
                    : (long)(wp->w_cursor.lnum));
-       len = STRLEN(buffer);
-       col_print(buffer + len, RULER_BUF_LEN - len,
+       bufferlen += col_print(buffer + bufferlen, RULER_BUF_LEN - bufferlen,
                        empty_line ? 0 : (int)wp->w_cursor.col + 1,
                        (int)virtcol + 1);
 
@@ -742,56 +732,60 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
         * On the last line, don't print in the last column (scrolls the
         * screen up on some terminals).
         */
-       i = (int)STRLEN(buffer);
-       get_rel_pos(wp, buffer + i + 1, RULER_BUF_LEN - i - 1);
-       o = i + vim_strsize(buffer + i + 1);
+       rel_poslen = get_rel_pos(wp, rel_pos, RULER_BUF_LEN);
+       n1 = bufferlen + vim_strsize(rel_pos);
        if (wp->w_status_height == 0)   // can't use last char of screen
-           ++o;
+           ++n1;
+
        this_ru_col = ru_col - (Columns - width);
-       if (this_ru_col < 0)
-           this_ru_col = 0;
        // Never use more than half the window/screen width, leave the other
        // half for the filename.
-       if (this_ru_col < (width + 1) / 2)
-           this_ru_col = (width + 1) / 2;
-       if (this_ru_col + o < width)
-       {
-           // need at least 3 chars left for get_rel_pos() + NUL
-           while (this_ru_col + o < width && RULER_BUF_LEN > i + 4)
+       n2 = (width + 1) / 2;
+       if (this_ru_col < n2)
+           this_ru_col = n2;
+       if (this_ru_col + n1 < width)
+       {
+           // need at least space for rel_pos + NUL
+           while (this_ru_col + n1 < width
+                   && RULER_BUF_LEN > bufferlen + rel_poslen + 1)      // +1 for NUL
            {
                if (has_mbyte)
-                   i += (*mb_char2bytes)(fillchar, buffer + i);
+                   bufferlen += (*mb_char2bytes)(fillchar, buffer + bufferlen);
                else
-                   buffer[i++] = fillchar;
-               ++o;
+                   buffer[bufferlen++] = fillchar;
+               ++n1;
            }
-           get_rel_pos(wp, buffer + i, RULER_BUF_LEN - i);
+           bufferlen += vim_snprintf((char *)buffer + bufferlen, RULER_BUF_LEN - bufferlen,
+                           "%s", rel_pos);
        }
        // Truncate at window boundary.
        if (has_mbyte)
        {
-           o = 0;
-           for (i = 0; buffer[i] != NUL; i += (*mb_ptr2len)(buffer + i))
+           for (n1 = 0, n2 = 0; buffer[n1] != NUL; n1 += (*mb_ptr2len)(buffer + n1))
            {
-               o += (*mb_ptr2cells)(buffer + i);
-               if (this_ru_col + o > width)
+               n2 += (*mb_ptr2cells)(buffer + n1);
+               if (this_ru_col + n2 > width)
                {
-                   buffer[i] = NUL;
+                   bufferlen = n1;
+                   buffer[bufferlen] = NUL;
                    break;
                }
            }
        }
-       else if (this_ru_col + (int)STRLEN(buffer) > width)
-           buffer[width - this_ru_col] = NUL;
+       else if (this_ru_col + bufferlen > width)
+       {
+           bufferlen = width - this_ru_col;
+           buffer[bufferlen] = NUL;
+       }
 
        screen_puts(buffer, row, this_ru_col + off, attr);
-       i = redraw_cmdline;
+       n1 = redraw_cmdline;
        screen_fill(row, row + 1,
-               this_ru_col + off + (int)STRLEN(buffer),
+               this_ru_col + off + bufferlen,
                (off + width),
                fillchar, fillchar, attr);
        // don't redraw the cmdline because of showing the ruler
-       redraw_cmdline = i;
+       redraw_cmdline = n1;
        wp->w_ru_cursor = wp->w_cursor;
        wp->w_ru_virtcol = wp->w_virtcol;
        wp->w_ru_empty = empty_line;
@@ -948,9 +942,10 @@ text_to_screenline(win_T *wp, char_u *text, int col)
     else
     {
        int len = (int)STRLEN(text);
+       int n = wp->w_width - col;
 
-       if (len > wp->w_width - col)
-           len = wp->w_width - col;
+       if (len > n)
+           len = n;
        if (len > 0)
        {
 #ifdef FEAT_RIGHTLEFT
@@ -1217,7 +1212,7 @@ fold_line(
                }
            }
 
-           sprintf((char *)buf, fmt, w, num);
+           vim_snprintf((char *)buf, sizeof(buf), fmt, w, num);
 #ifdef FEAT_RIGHTLEFT
            if (wp->w_p_rl)
                // the line number isn't reversed
@@ -2048,8 +2043,7 @@ win_update(win_T *wp)
                        {
                            colnr_T t;
 
-                           pos.col = (int)STRLEN(ml_get_buf(wp->w_buffer,
-                                                            pos.lnum, FALSE));
+                           pos.col = (int)ml_get_buf_len(wp->w_buffer, pos.lnum);
                            getvvcol(wp, &pos, NULL, NULL, &t);
                            if (toc < t)
                                toc = t;
index dc68ca8fc123f4e730e33f16b49481c51038251f..5491940daf35c087a5b86817dec669307b7b4430 100644 (file)
@@ -44,12 +44,12 @@ void buflist_altfpos(win_T *win);
 int otherfile(char_u *ffname);
 void buf_setino(buf_T *buf);
 void fileinfo(int fullname, int shorthelp, int dont_truncate);
-void col_print(char_u *buf, size_t buflen, int col, int vcol);
+int col_print(char_u *buf, size_t buflen, int col, int vcol);
 void maketitle(void);
 void resettitle(void);
 void free_titles(void);
 int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab);
-void get_rel_pos(win_T *wp, char_u *buf, int buflen);
+int get_rel_pos(win_T *wp, char_u *buf, int buflen);
 char_u *fix_fname(char_u *fname);
 void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname);
 void ex_buffer_all(exarg_T *eap);
index 35d300213b6162a4e30f2ca666731ef2b1d1bac5..8fb17ae87a6360fccc0c6bdab35af08b5f89bc6b 100644 (file)
@@ -968,20 +968,21 @@ get_keymap_str(
     int                len)        // length of buffer
 {
     char_u     *p;
+    int                plen;
 
     if (wp->w_buffer->b_p_iminsert != B_IMODE_LMAP)
-       return FALSE;
+       return 0;
 
 #ifdef FEAT_EVAL
     buf_T      *old_curbuf = curbuf;
     win_T      *old_curwin = curwin;
+    char_u     to_evaluate[] = "b:keymap_name";
     char_u     *s;
 
     curbuf = wp->w_buffer;
     curwin = wp;
-    STRCPY(buf, "b:keymap_name");      // must be writable
     ++emsg_skip;
-    s = p = eval_to_string(buf, FALSE, FALSE);
+    s = p = eval_to_string(to_evaluate, FALSE, FALSE);
     --emsg_skip;
     curbuf = old_curbuf;
     curwin = old_curwin;
@@ -995,12 +996,17 @@ get_keymap_str(
 #endif
            p = (char_u *)"lang";
     }
-    if (vim_snprintf((char *)buf, len, (char *)fmt, p) > len - 1)
-       buf[0] = NUL;
+    plen = vim_snprintf((char *)buf, len, (char *)fmt, p);
 #ifdef FEAT_EVAL
     vim_free(s);
 #endif
-    return buf[0] != NUL;
+    if (plen < 0 || plen > len - 1)
+    {
+       buf[0] = NUL;
+       plen = 0;
+    }
+
+    return plen;
 }
 
 #if defined(FEAT_STL_OPT) || defined(PROTO)
@@ -4133,7 +4139,7 @@ showmode(void)
                    else
 # endif
                        if (get_keymap_str(curwin, (char_u *)" (%s)",
-                                                          NameBuff, MAXPATHL))
+                                                          NameBuff, MAXPATHL) > 0)
                            msg_puts_attr((char *)NameBuff, attr);
                }
 #endif
index 38f46927d042a8f879d9aea8c2e4211e4ddc6afc..22efc7e6bb8fb44dcd1ec97ed5bc15c5c0d82101 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    997,
 /**/
     996,
 /**/