vim-patch:9.1.1151: too many strlen() calls in getchar.c

Problem:  too many strlen() calls in getchar.c
Solution: store last inserted and recorded lengths,
          add functions to retrieve those and use those
          functions (John Marriott)

closes: vim/vim#16720

d3c4b7e946

Co-authored-by: John Marriott <basilisk@internode.on.net>
This commit is contained in:
zeertzjq
2025-02-27 08:44:42 +08:00
parent 3cce657031
commit e1a3128ec4
3 changed files with 36 additions and 15 deletions

View File

@@ -339,7 +339,7 @@ static void insert_enter(InsertState *s)
if (s->ptr == NULL) { if (s->ptr == NULL) {
new_insert_skip = 0; new_insert_skip = 0;
} else { } else {
new_insert_skip = (int)strlen(s->ptr); new_insert_skip = (int)get_inserted_len();
xfree(s->ptr); xfree(s->ptr);
} }
@@ -2342,7 +2342,7 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
// Don't do it when "restart_edit" was set and nothing was inserted, // Don't do it when "restart_edit" was set and nothing was inserted,
// otherwise CTRL-O w and then <Left> will clear "last_insert". // otherwise CTRL-O w and then <Left> will clear "last_insert".
char *ptr = get_inserted(); char *ptr = get_inserted();
int added = ptr == NULL ? 0 : (int)strlen(ptr) - new_insert_skip; int added = ptr == NULL ? 0 : (int)get_inserted_len() - new_insert_skip;
if (did_restart_edit == 0 || added > 0) { if (did_restart_edit == 0 || added > 0) {
xfree(last_insert); xfree(last_insert);
last_insert = ptr; last_insert = ptr;
@@ -2772,8 +2772,8 @@ char *get_last_insert_save(void)
if (last_insert == NULL) { if (last_insert == NULL) {
return NULL; return NULL;
} }
char *s = xstrdup(last_insert + last_insert_skip); size_t len = strlen(last_insert + last_insert_skip);
int len = (int)strlen(s); char *s = xmemdupz(last_insert + last_insert_skip, len);
if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC
s[len - 1] = NUL; s[len - 1] = NUL;
} }

View File

@@ -155,6 +155,11 @@ static uint8_t noremapbuf_init[TYPELEN_INIT]; ///< initial typebuf.tb_noremap
static size_t last_recorded_len = 0; ///< number of last recorded chars static size_t last_recorded_len = 0; ///< number of last recorded chars
static size_t last_get_recorded_len = 0; ///< length of the string returned from the
///< last call to get_recorded()
static size_t last_get_inserted_len = 0; ///< length of the string returned from the
///< last call to get_inserted()
enum { enum {
KEYLEN_PART_KEY = -1, ///< keylen value for incomplete key-code KEYLEN_PART_KEY = -1, ///< keylen value for incomplete key-code
KEYLEN_PART_MAP = -2, ///< keylen value for incomplete mapping KEYLEN_PART_MAP = -2, ///< keylen value for incomplete mapping
@@ -225,31 +230,48 @@ static char *get_buffcont(buffheader_T *buffer, int dozero, size_t *len)
/// K_SPECIAL in the returned string is escaped. /// K_SPECIAL in the returned string is escaped.
char *get_recorded(void) char *get_recorded(void)
{ {
size_t len; char *p = get_buffcont(&recordbuff, true, &last_get_recorded_len);
char *p = get_buffcont(&recordbuff, true, &len); if (p == NULL) {
return NULL;
}
free_buff(&recordbuff); free_buff(&recordbuff);
// Remove the characters that were added the last time, these must be the // Remove the characters that were added the last time, these must be the
// (possibly mapped) characters that stopped the recording. // (possibly mapped) characters that stopped the recording.
if (len >= last_recorded_len) { if (last_get_recorded_len >= last_recorded_len) {
len -= last_recorded_len; last_get_recorded_len -= last_recorded_len;
p[len] = NUL; p[last_get_recorded_len] = NUL;
} }
// When stopping recording from Insert mode with CTRL-O q, also remove the // When stopping recording from Insert mode with CTRL-O q, also remove the
// CTRL-O. // CTRL-O.
if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O) { if (last_get_recorded_len > 0 && restart_edit != 0
p[len - 1] = NUL; && p[last_get_recorded_len - 1] == Ctrl_O) {
last_get_recorded_len--;
p[last_get_recorded_len] = NUL;
} }
return p; return p;
} }
/// Return the length of string returned from the last call of get_recorded().
size_t get_recorded_len(void)
{
return last_get_recorded_len;
}
/// Return the contents of the redo buffer as a single string. /// Return the contents of the redo buffer as a single string.
/// K_SPECIAL in the returned string is escaped. /// K_SPECIAL in the returned string is escaped.
char *get_inserted(void) char *get_inserted(void)
{ {
return get_buffcont(&redobuff, false, NULL); return get_buffcont(&redobuff, false, &last_get_inserted_len);
}
/// Return the length of string returned from the last call of get_inserted().
size_t get_inserted_len(void)
{
return last_get_inserted_len;
} }
/// Add string after the current block of the given buffer /// Add string after the current block of the given buffer

View File

@@ -1039,7 +1039,7 @@ int do_record(int c)
// restore the current register name. // restore the current register name.
yankreg_T *old_y_previous = y_previous; yankreg_T *old_y_previous = y_previous;
retval = stuff_yank(regname, p); retval = stuff_yank(regname, p, get_recorded_len());
y_previous = old_y_previous; y_previous = old_y_previous;
} }
@@ -1051,7 +1051,7 @@ int do_record(int c)
/// uppercase). "p" must have been allocated. /// uppercase). "p" must have been allocated.
/// ///
/// @return FAIL for failure, OK otherwise /// @return FAIL for failure, OK otherwise
static int stuff_yank(int regname, char *p) static int stuff_yank(int regname, char *p, size_t plen)
{ {
// check for read-only register // check for read-only register
if (regname != 0 && !valid_yank_reg(regname, true)) { if (regname != 0 && !valid_yank_reg(regname, true)) {
@@ -1063,7 +1063,6 @@ static int stuff_yank(int regname, char *p)
return OK; return OK;
} }
const size_t plen = strlen(p);
yankreg_T *reg = get_yank_register(regname, YREG_YANK); yankreg_T *reg = get_yank_register(regname, YREG_YANK);
if (is_append_register(regname) && reg->y_array != NULL) { if (is_append_register(regname) && reg->y_array != NULL) {
String *pp = &(reg->y_array[reg->y_size - 1]); String *pp = &(reg->y_array[reg->y_size - 1]);