vim-patch:9.1.1137: ins_str() is inefficient by calling STRLEN() (#32591)

Problem:  ins_str() is inefficient by calling STRLLEN()
Solution: refactor ins_str() to take a length argument
          and let all callers provide the correct length
          when calling ins_str() (John Marriott)

closes: vim/vim#16711

f4b36417e8

Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
zeertzjq
2025-02-23 16:52:44 +08:00
committed by GitHub
parent 5a41f7e69c
commit 16e6f6e584
5 changed files with 44 additions and 42 deletions

View File

@@ -804,9 +804,8 @@ void ins_char_bytes(char *buf, size_t charlen)
/// Insert a string at the cursor position.
/// Note: Does NOT handle Replace mode.
/// Caller must have prepared for undo.
void ins_str(char *s)
void ins_str(char *s, size_t slen)
{
int newlen = (int)strlen(s);
linenr_T lnum = curwin->w_cursor.lnum;
if (virtual_active(curwin) && curwin->w_cursor.coladd > 0) {
@@ -817,17 +816,17 @@ void ins_str(char *s)
char *oldp = ml_get(lnum);
int oldlen = ml_get_len(lnum);
char *newp = xmalloc((size_t)oldlen + (size_t)newlen + 1);
char *newp = xmalloc((size_t)oldlen + slen + 1);
if (col > 0) {
memmove(newp, oldp, (size_t)col);
}
memmove(newp + col, s, (size_t)newlen);
memmove(newp + col, s, slen);
int bytes = oldlen - col + 1;
assert(bytes >= 0);
memmove(newp + col + newlen, oldp + col, (size_t)bytes);
memmove(newp + col + slen, oldp + col, (size_t)bytes);
ml_replace(lnum, newp, false);
inserted_bytes(lnum, col, 0, newlen);
curwin->w_cursor.col += newlen;
inserted_bytes(lnum, col, 0, (int)slen);
curwin->w_cursor.col += (int)slen;
}
// Delete one character under the cursor.

View File

@@ -1737,11 +1737,11 @@ void change_indent(int type, int amount, int round, bool call_changed_bytes)
// the right screen column.
if (vcol != (int)curwin->w_virtcol) {
curwin->w_cursor.col = (colnr_T)new_cursor_col;
size_t i = (size_t)(curwin->w_virtcol - vcol);
char *ptr = xmallocz(i);
memset(ptr, ' ', i);
new_cursor_col += (int)i;
ins_str(ptr);
const size_t ptrlen = (size_t)(curwin->w_virtcol - vcol);
char *ptr = xmallocz(ptrlen);
memset(ptr, ' ', ptrlen);
new_cursor_col += (int)ptrlen;
ins_str(ptr, ptrlen);
xfree(ptr);
}
@@ -2014,7 +2014,7 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
return;
}
p[len - 1] = NUL;
ins_str(p);
ins_str(p, (size_t)(len - 1));
AppendToRedobuffLit(p, -1);
ctrlv = false;
}
@@ -2195,7 +2195,7 @@ void insertchar(int c, int flags, int second_indent)
do_digraph(-1); // clear digraphs
do_digraph((uint8_t)buf[i - 1]); // may be the start of a digraph
buf[i] = NUL;
ins_str(buf);
ins_str(buf, (size_t)i);
if (flags & INSCHAR_CTRLV) {
redo_literal((uint8_t)(*buf));
i = 1;
@@ -3860,7 +3860,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
if (State & VREPLACE_FLAG) {
ins_char(' ');
} else {
ins_str(" ");
ins_str(S_LEN(" "));
if ((State & REPLACE_FLAG)) {
replace_push_nul();
}
@@ -4270,7 +4270,7 @@ static bool ins_tab(void)
if (State & VREPLACE_FLAG) {
ins_char(' ');
} else {
ins_str(" ");
ins_str(S_LEN(" "));
if (State & REPLACE_FLAG) { // no char replaced
replace_push_nul();
}

View File

@@ -3781,17 +3781,16 @@ void ins_compl_delete(bool new_leader)
curwin->w_cursor.col = compl_ins_end_col;
}
char *remaining = NULL;
String remaining = STRING_INIT;
if (curwin->w_cursor.lnum > compl_lnum) {
if (curwin->w_cursor.col < get_cursor_line_len()) {
char *line = get_cursor_line_ptr();
remaining = xstrdup(line + curwin->w_cursor.col);
remaining = cbuf_to_string(get_cursor_pos_ptr(), (size_t)get_cursor_pos_len());
}
while (curwin->w_cursor.lnum > compl_lnum) {
if (ml_delete(curwin->w_cursor.lnum, false) == FAIL) {
if (remaining) {
XFREE_CLEAR(remaining);
if (remaining.data) {
xfree(remaining.data);
}
return;
}
@@ -3804,8 +3803,8 @@ void ins_compl_delete(bool new_leader)
if ((int)curwin->w_cursor.col > col) {
if (stop_arrow() == FAIL) {
if (remaining) {
XFREE_CLEAR(remaining);
if (remaining.data) {
xfree(remaining.data);
}
return;
}
@@ -3813,11 +3812,11 @@ void ins_compl_delete(bool new_leader)
compl_ins_end_col = curwin->w_cursor.col;
}
if (remaining != NULL) {
if (remaining.data != NULL) {
orig_col = curwin->w_cursor.col;
ins_str(remaining);
ins_str(remaining.data, remaining.size);
curwin->w_cursor.col = orig_col;
xfree(remaining);
xfree(remaining.data);
}
// TODO(vim): is this sufficient for redrawing? Redrawing everything

View File

@@ -4513,8 +4513,6 @@ void op_addsub(oparg_T *oap, linenr_T Prenum1, bool g_cmd)
/// @return true if some character was changed.
bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
{
char *buf1 = NULL;
char buf2[NUMBUFLEN];
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
uvarnumber_T n;
@@ -4778,7 +4776,7 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
// Prepare the leading characters in buf1[].
// When there are many leading zeros it could be very long.
// Allocate a bit too much.
buf1 = xmalloc((size_t)length + NUMBUFLEN);
char *buf1 = xmalloc((size_t)length + NUMBUFLEN);
ptr = buf1;
if (negative && (!visual || was_positive)) {
*ptr++ = '-';
@@ -4793,9 +4791,10 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
// Put the number characters in buf2[].
char buf2[NUMBUFLEN];
int buf2len = 0;
if (pre == 'b' || pre == 'B') {
size_t bits = 0;
size_t i = 0;
// leading zeros
for (bits = 8 * sizeof(n); bits > 0; bits--) {
@@ -4804,21 +4803,21 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
}
while (bits > 0 && i < NUMBUFLEN - 1) {
buf2[i++] = ((n >> --bits) & 0x1) ? '1' : '0';
while (bits > 0 && buf2len < NUMBUFLEN - 1) {
buf2[buf2len++] = ((n >> --bits) & 0x1) ? '1' : '0';
}
buf2[i] = NUL;
buf2[buf2len] = NUL;
} else if (pre == 0) {
vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
buf2len = vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') {
vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
buf2len = vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
} else if (hexupper) {
vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
buf2len = vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
} else {
vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
buf2len = vim_snprintf(buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
}
length -= (int)strlen(buf2);
length -= buf2len;
// Adjust number of zeros to the new number of digits, so the
// total length of the number remains the same.
@@ -4830,8 +4829,14 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
}
*ptr = NUL;
strcat(buf1, buf2);
ins_str(buf1); // insert the new number
int buf1len = (int)(ptr - buf1);
STRCPY(buf1 + buf1len, buf2);
buf1len += buf2len;
ins_str(buf1, (size_t)buf1len); // insert the new number
xfree(buf1);
endpos = curwin->w_cursor;
if (curwin->w_cursor.col) {
curwin->w_cursor.col--;
@@ -4848,7 +4853,6 @@ bool do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
}
theend:
xfree(buf1);
if (visual) {
curwin->w_cursor = save_cursor;
} else if (did_change) {

View File

@@ -413,7 +413,7 @@ void internal_format(int textwidth, int second_indent, int flags, bool format_on
// add the additional whitespace needed after the
// comment leader for the numbered list.
for (int i = 0; i < padding; i++) {
ins_str(" ");
ins_str(S_LEN(" "));
}
} else {
set_indent(second_indent, SIN_CHANGED);