patch 9.1.0997: too many strlen() calls in drawscreen.c
Commit:
https://github.com/vim/vim/commit/a21240b97debea2e087aee6ad1488b5f075d1259
Author: John Marriott <[email protected]>
Date: Wed Jan 8 20:10:59 2025 +0100
patch 9.1.0997: too many strlen() calls in drawscreen.c
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 <[email protected]>
Signed-off-by: Christian Brabandt <[email protected]>
diff --git a/src/buffer.c b/src/buffer.c
index 147d20dc7..a92555219 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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;
}
/*
diff --git a/src/drawscreen.c b/src/drawscreen.c
index 778cda4d4..36034cc9d 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -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;
diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro
index dc68ca8fc..5491940da 100644
--- a/src/proto/buffer.pro
+++ b/src/proto/buffer.pro
@@ -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);
diff --git a/src/screen.c b/src/screen.c
index 35d300213..8fb17ae87 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -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
diff --git a/src/version.c b/src/version.c
index 38f46927d..22efc7e6b 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 */
+/**/
+ 997,
/**/
996,
/**/
--
--
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 [email protected].
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/E1tVbWC-00GO5B-LE%40256bit.org.