mirror of
https://github.com/vim/vim.git
synced 2025-09-27 04:14:06 -04:00
patch 9.1.0851: too many strlen() calls in getchar.c
Problem: too many strlen() calls in getchar.c Solution: refactor code and reduce strlen() calls (John Marriott) closes: #16017 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
56d45f1b66
commit
e7a1bbf210
101
src/getchar.c
101
src/getchar.c
@@ -36,9 +36,9 @@
|
|||||||
|
|
||||||
#define MINIMAL_SIZE 20 // minimal size for b_str
|
#define MINIMAL_SIZE 20 // minimal size for b_str
|
||||||
|
|
||||||
static buffheader_T redobuff = {{NULL, {NUL}}, NULL, 0, 0};
|
static buffheader_T redobuff = {{NULL, 0, {NUL}}, NULL, 0, 0, FALSE};
|
||||||
static buffheader_T old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
|
static buffheader_T old_redobuff = {{NULL, 0, {NUL}}, NULL, 0, 0, FALSE};
|
||||||
static buffheader_T recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
|
static buffheader_T recordbuff = {{NULL, 0, {NUL}}, NULL, 0, 0, FALSE};
|
||||||
|
|
||||||
static int typeahead_char = 0; // typeahead char that's not flushed
|
static int typeahead_char = 0; // typeahead char that's not flushed
|
||||||
|
|
||||||
@@ -129,17 +129,19 @@ free_buff(buffheader_T *buf)
|
|||||||
static char_u *
|
static char_u *
|
||||||
get_buffcont(
|
get_buffcont(
|
||||||
buffheader_T *buffer,
|
buffheader_T *buffer,
|
||||||
int dozero) // count == zero is not an error
|
int dozero, // count == zero is not an error
|
||||||
|
size_t *len) // the length of the returned buffer
|
||||||
{
|
{
|
||||||
long_u count = 0;
|
long_u count = 0;
|
||||||
char_u *p = NULL;
|
char_u *p = NULL;
|
||||||
char_u *p2;
|
char_u *p2;
|
||||||
char_u *str;
|
char_u *str;
|
||||||
buffblock_T *bp;
|
buffblock_T *bp;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
// compute the total length of the string
|
// compute the total length of the string
|
||||||
for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
|
for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
|
||||||
count += (long_u)STRLEN(bp->b_str);
|
count += (long_u)bp->b_strlen;
|
||||||
|
|
||||||
if ((count > 0 || dozero) && (p = alloc(count + 1)) != NULL)
|
if ((count > 0 || dozero) && (p = alloc(count + 1)) != NULL)
|
||||||
{
|
{
|
||||||
@@ -148,7 +150,12 @@ get_buffcont(
|
|||||||
for (str = bp->b_str; *str; )
|
for (str = bp->b_str; *str; )
|
||||||
*p2++ = *str++;
|
*p2++ = *str++;
|
||||||
*p2 = NUL;
|
*p2 = NUL;
|
||||||
|
i = (size_t)(p2 - p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (len != NULL)
|
||||||
|
*len = i;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,14 +170,13 @@ get_recorded(void)
|
|||||||
char_u *p;
|
char_u *p;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
p = get_buffcont(&recordbuff, TRUE);
|
p = get_buffcont(&recordbuff, TRUE, &len);
|
||||||
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.
|
||||||
*/
|
*/
|
||||||
len = STRLEN(p);
|
|
||||||
if (len >= last_recorded_len)
|
if (len >= last_recorded_len)
|
||||||
{
|
{
|
||||||
len -= last_recorded_len;
|
len -= last_recorded_len;
|
||||||
@@ -194,7 +200,7 @@ get_recorded(void)
|
|||||||
char_u *
|
char_u *
|
||||||
get_inserted(void)
|
get_inserted(void)
|
||||||
{
|
{
|
||||||
return get_buffcont(&redobuff, FALSE);
|
return get_buffcont(&redobuff, FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -207,9 +213,6 @@ add_buff(
|
|||||||
char_u *s,
|
char_u *s,
|
||||||
long slen) // length of "s" or -1
|
long slen) // length of "s" or -1
|
||||||
{
|
{
|
||||||
buffblock_T *p;
|
|
||||||
long_u len;
|
|
||||||
|
|
||||||
if (slen < 0)
|
if (slen < 0)
|
||||||
slen = (long)STRLEN(s);
|
slen = (long)STRLEN(s);
|
||||||
if (slen == 0) // don't add empty strings
|
if (slen == 0) // don't add empty strings
|
||||||
@@ -217,8 +220,8 @@ add_buff(
|
|||||||
|
|
||||||
if (buf->bh_first.b_next == NULL) // first add to list
|
if (buf->bh_first.b_next == NULL) // first add to list
|
||||||
{
|
{
|
||||||
buf->bh_space = 0;
|
|
||||||
buf->bh_curr = &(buf->bh_first);
|
buf->bh_curr = &(buf->bh_first);
|
||||||
|
buf->bh_create_newblock = TRUE;
|
||||||
}
|
}
|
||||||
else if (buf->bh_curr == NULL) // buffer has already been read
|
else if (buf->bh_curr == NULL) // buffer has already been read
|
||||||
{
|
{
|
||||||
@@ -226,19 +229,26 @@ add_buff(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (buf->bh_index != 0)
|
else if (buf->bh_index != 0)
|
||||||
|
{
|
||||||
mch_memmove(buf->bh_first.b_next->b_str,
|
mch_memmove(buf->bh_first.b_next->b_str,
|
||||||
buf->bh_first.b_next->b_str + buf->bh_index,
|
buf->bh_first.b_next->b_str + buf->bh_index,
|
||||||
STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1);
|
(buf->bh_first.b_next->b_strlen - buf->bh_index) + 1);
|
||||||
|
buf->bh_first.b_next->b_strlen -= buf->bh_index;
|
||||||
|
buf->bh_space += buf->bh_index;
|
||||||
|
}
|
||||||
buf->bh_index = 0;
|
buf->bh_index = 0;
|
||||||
|
|
||||||
if (buf->bh_space >= (int)slen)
|
if (!buf->bh_create_newblock && buf->bh_space >= (int)slen)
|
||||||
{
|
{
|
||||||
len = (long_u)STRLEN(buf->bh_curr->b_str);
|
vim_strncpy(buf->bh_curr->b_str + buf->bh_curr->b_strlen, s, (size_t)slen);
|
||||||
vim_strncpy(buf->bh_curr->b_str + len, s, (size_t)slen);
|
buf->bh_curr->b_strlen += slen;
|
||||||
buf->bh_space -= slen;
|
buf->bh_space -= slen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
long_u len;
|
||||||
|
buffblock_T *p;
|
||||||
|
|
||||||
if (slen < MINIMAL_SIZE)
|
if (slen < MINIMAL_SIZE)
|
||||||
len = MINIMAL_SIZE;
|
len = MINIMAL_SIZE;
|
||||||
else
|
else
|
||||||
@@ -246,8 +256,10 @@ add_buff(
|
|||||||
p = alloc(offsetof(buffblock_T, b_str) + len + 1);
|
p = alloc(offsetof(buffblock_T, b_str) + len + 1);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return; // no space, just forget it
|
return; // no space, just forget it
|
||||||
buf->bh_space = (int)(len - slen);
|
|
||||||
vim_strncpy(p->b_str, s, (size_t)slen);
|
vim_strncpy(p->b_str, s, (size_t)slen);
|
||||||
|
p->b_strlen = slen;
|
||||||
|
buf->bh_space = (int)(len - slen);
|
||||||
|
buf->bh_create_newblock = FALSE;
|
||||||
|
|
||||||
p->b_next = buf->bh_curr->b_next;
|
p->b_next = buf->bh_curr->b_next;
|
||||||
buf->bh_curr->b_next = p;
|
buf->bh_curr->b_next = p;
|
||||||
@@ -262,15 +274,13 @@ add_buff(
|
|||||||
static void
|
static void
|
||||||
delete_buff_tail(buffheader_T *buf, int slen)
|
delete_buff_tail(buffheader_T *buf, int slen)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
|
|
||||||
if (buf->bh_curr == NULL)
|
if (buf->bh_curr == NULL)
|
||||||
return; // nothing to delete
|
return; // nothing to delete
|
||||||
len = (int)STRLEN(buf->bh_curr->b_str);
|
if (buf->bh_curr->b_strlen < (size_t)slen)
|
||||||
if (len < slen)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
buf->bh_curr->b_str[len - slen] = NUL;
|
buf->bh_curr->b_str[buf->bh_curr->b_strlen - (size_t)slen] = NUL;
|
||||||
|
buf->bh_curr->b_strlen -= slen;
|
||||||
buf->bh_space += slen;
|
buf->bh_space += slen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,9 +291,10 @@ delete_buff_tail(buffheader_T *buf, int slen)
|
|||||||
add_num_buff(buffheader_T *buf, long n)
|
add_num_buff(buffheader_T *buf, long n)
|
||||||
{
|
{
|
||||||
char_u number[32];
|
char_u number[32];
|
||||||
|
int numberlen;
|
||||||
|
|
||||||
sprintf((char *)number, "%ld", n);
|
numberlen = vim_snprintf((char *)number, sizeof(number), "%ld", n);
|
||||||
add_buff(buf, number, -1L);
|
add_buff(buf, number, (long)numberlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -297,6 +308,7 @@ add_char_buff(buffheader_T *buf, int c)
|
|||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
char_u temp[4];
|
char_u temp[4];
|
||||||
|
long templen;
|
||||||
|
|
||||||
if (IS_SPECIAL(c))
|
if (IS_SPECIAL(c))
|
||||||
len = 1;
|
len = 1;
|
||||||
@@ -314,6 +326,7 @@ add_char_buff(buffheader_T *buf, int c)
|
|||||||
temp[1] = K_SECOND(c);
|
temp[1] = K_SECOND(c);
|
||||||
temp[2] = K_THIRD(c);
|
temp[2] = K_THIRD(c);
|
||||||
temp[3] = NUL;
|
temp[3] = NUL;
|
||||||
|
templen = 3;
|
||||||
}
|
}
|
||||||
#ifdef FEAT_GUI
|
#ifdef FEAT_GUI
|
||||||
else if (c == CSI)
|
else if (c == CSI)
|
||||||
@@ -323,22 +336,24 @@ add_char_buff(buffheader_T *buf, int c)
|
|||||||
temp[1] = KS_EXTRA;
|
temp[1] = KS_EXTRA;
|
||||||
temp[2] = (int)KE_CSI;
|
temp[2] = (int)KE_CSI;
|
||||||
temp[3] = NUL;
|
temp[3] = NUL;
|
||||||
|
templen = 3;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp[0] = c;
|
temp[0] = c;
|
||||||
temp[1] = NUL;
|
temp[1] = NUL;
|
||||||
|
templen = 1;
|
||||||
}
|
}
|
||||||
add_buff(buf, temp, -1L);
|
add_buff(buf, temp, templen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// First read ahead buffer. Used for translated commands.
|
// First read ahead buffer. Used for translated commands.
|
||||||
static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0};
|
static buffheader_T readbuf1 = {{NULL, 0, {NUL}}, NULL, 0, 0, FALSE};
|
||||||
|
|
||||||
// Second read ahead buffer. Used for redo.
|
// Second read ahead buffer. Used for redo.
|
||||||
static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0};
|
static buffheader_T readbuf2 = {{NULL, 0, {NUL}}, NULL, 0, 0, FALSE};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get one byte from the read buffers. Use readbuf1 one first, use readbuf2
|
* Get one byte from the read buffers. Use readbuf1 one first, use readbuf2
|
||||||
@@ -390,12 +405,12 @@ start_stuff(void)
|
|||||||
if (readbuf1.bh_first.b_next != NULL)
|
if (readbuf1.bh_first.b_next != NULL)
|
||||||
{
|
{
|
||||||
readbuf1.bh_curr = &(readbuf1.bh_first);
|
readbuf1.bh_curr = &(readbuf1.bh_first);
|
||||||
readbuf1.bh_space = 0;
|
readbuf1.bh_create_newblock = TRUE; // force a new block to be created (see add_buff())
|
||||||
}
|
}
|
||||||
if (readbuf2.bh_first.b_next != NULL)
|
if (readbuf2.bh_first.b_next != NULL)
|
||||||
{
|
{
|
||||||
readbuf2.bh_curr = &(readbuf2.bh_first);
|
readbuf2.bh_curr = &(readbuf2.bh_first);
|
||||||
readbuf2.bh_space = 0;
|
readbuf2.bh_create_newblock = TRUE; // force a new block to be created (see add_buff())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,6 +544,7 @@ CancelRedo(void)
|
|||||||
saveRedobuff(save_redo_T *save_redo)
|
saveRedobuff(save_redo_T *save_redo)
|
||||||
{
|
{
|
||||||
char_u *s;
|
char_u *s;
|
||||||
|
size_t slen;
|
||||||
|
|
||||||
save_redo->sr_redobuff = redobuff;
|
save_redo->sr_redobuff = redobuff;
|
||||||
redobuff.bh_first.b_next = NULL;
|
redobuff.bh_first.b_next = NULL;
|
||||||
@@ -536,11 +552,11 @@ saveRedobuff(save_redo_T *save_redo)
|
|||||||
old_redobuff.bh_first.b_next = NULL;
|
old_redobuff.bh_first.b_next = NULL;
|
||||||
|
|
||||||
// Make a copy, so that ":normal ." in a function works.
|
// Make a copy, so that ":normal ." in a function works.
|
||||||
s = get_buffcont(&save_redo->sr_redobuff, FALSE);
|
s = get_buffcont(&save_redo->sr_redobuff, FALSE, &slen);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
add_buff(&redobuff, s, -1L);
|
add_buff(&redobuff, s, (long)slen);
|
||||||
vim_free(s);
|
vim_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2219,13 +2235,15 @@ do_key_input_pre(int c)
|
|||||||
// character. Only use it when changed, otherwise continue with the
|
// character. Only use it when changed, otherwise continue with the
|
||||||
// original character.
|
// original character.
|
||||||
char_u *v_char;
|
char_u *v_char;
|
||||||
|
size_t v_charlen;
|
||||||
|
|
||||||
v_char = get_vim_var_str(VV_CHAR);
|
v_char = get_vim_var_str(VV_CHAR);
|
||||||
|
v_charlen = STRLEN(v_char);
|
||||||
|
|
||||||
// Convert special bytes when it is special string.
|
// Convert special bytes when it is special string.
|
||||||
if (STRLEN(v_char) >= 3 && v_char[0] == K_SPECIAL)
|
if (v_charlen >= 3 && v_char[0] == K_SPECIAL)
|
||||||
res = TERMCAP2KEY(v_char[1], v_char[2]);
|
res = TERMCAP2KEY(v_char[1], v_char[2]);
|
||||||
else if (STRLEN(v_char) > 0)
|
else if (v_charlen > 0)
|
||||||
res = PTR2CHAR(v_char);
|
res = PTR2CHAR(v_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2438,9 +2456,9 @@ getchar_common(typval_T *argvars, typval_T *rettv)
|
|||||||
i += (*mb_char2bytes)(n, temp + i);
|
i += (*mb_char2bytes)(n, temp + i);
|
||||||
else
|
else
|
||||||
temp[i++] = n;
|
temp[i++] = n;
|
||||||
temp[i++] = NUL;
|
temp[i] = NUL;
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = vim_strsave(temp);
|
rettv->vval.v_string = vim_strnsave(temp, i);
|
||||||
|
|
||||||
if (is_mouse_key(n))
|
if (is_mouse_key(n))
|
||||||
{
|
{
|
||||||
@@ -2507,9 +2525,9 @@ f_getcharstr(typval_T *argvars, typval_T *rettv)
|
|||||||
else
|
else
|
||||||
temp[i++] = n;
|
temp[i++] = n;
|
||||||
}
|
}
|
||||||
temp[i++] = NUL;
|
temp[i] = NUL;
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = vim_strsave(temp);
|
rettv->vval.v_string = vim_strnsave(temp, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3256,7 +3274,7 @@ handle_mapping(
|
|||||||
buf[1] = KS_EXTRA;
|
buf[1] = KS_EXTRA;
|
||||||
buf[2] = KE_IGNORE;
|
buf[2] = KE_IGNORE;
|
||||||
buf[3] = NUL;
|
buf[3] = NUL;
|
||||||
map_str = vim_strsave(buf);
|
map_str = vim_strnsave(buf, 3);
|
||||||
if (State & MODE_CMDLINE)
|
if (State & MODE_CMDLINE)
|
||||||
{
|
{
|
||||||
// redraw the command below the error
|
// redraw the command below the error
|
||||||
@@ -4265,6 +4283,7 @@ getcmdkeycmd(
|
|||||||
may_add_last_used_map_to_redobuff(void)
|
may_add_last_used_map_to_redobuff(void)
|
||||||
{
|
{
|
||||||
char_u buf[3 + 20];
|
char_u buf[3 + 20];
|
||||||
|
int buflen;
|
||||||
int sid = -1;
|
int sid = -1;
|
||||||
|
|
||||||
if (last_used_map != NULL)
|
if (last_used_map != NULL)
|
||||||
@@ -4279,8 +4298,10 @@ may_add_last_used_map_to_redobuff(void)
|
|||||||
buf[0] = K_SPECIAL;
|
buf[0] = K_SPECIAL;
|
||||||
buf[1] = KS_EXTRA;
|
buf[1] = KS_EXTRA;
|
||||||
buf[2] = KE_SID;
|
buf[2] = KE_SID;
|
||||||
vim_snprintf((char *)buf + 3, 20, "%d;", sid);
|
buflen = 3;
|
||||||
add_buff(&redobuff, buf, -1L);
|
|
||||||
|
buflen += vim_snprintf((char *)buf + 3, 20, "%d;", sid);
|
||||||
|
add_buff(&redobuff, buf, (long)buflen);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -573,6 +573,7 @@ typedef struct buffheader buffheader_T;
|
|||||||
struct buffblock
|
struct buffblock
|
||||||
{
|
{
|
||||||
buffblock_T *b_next; // pointer to next buffblock
|
buffblock_T *b_next; // pointer to next buffblock
|
||||||
|
size_t b_strlen; // length of b_str, excluding the NUL
|
||||||
char_u b_str[1]; // contents (actually longer)
|
char_u b_str[1]; // contents (actually longer)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -585,6 +586,7 @@ struct buffheader
|
|||||||
buffblock_T *bh_curr; // buffblock for appending
|
buffblock_T *bh_curr; // buffblock for appending
|
||||||
int bh_index; // index for reading
|
int bh_index; // index for reading
|
||||||
int bh_space; // space in bh_curr for appending
|
int bh_space; // space in bh_curr for appending
|
||||||
|
int bh_create_newblock; // create a new block?
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
851,
|
||||||
/**/
|
/**/
|
||||||
850,
|
850,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user