forked from aniani/vim
patch 9.1.0843: too many strlen() calls in undo.c
Problem: too many strlen() calls in undo.c Solution: refactor code and remove strlen() calls, update test_undo.vim and close remaining open swap files (John Marriott) closes: #15995 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
39cd9061b1
commit
fd1a838d36
@ -397,6 +397,8 @@ typedef struct {
|
|||||||
char_u *ul_line; // text of the line
|
char_u *ul_line; // text of the line
|
||||||
long ul_len; // length of the line including NUL, plus text
|
long ul_len; // length of the line including NUL, plus text
|
||||||
// properties
|
// properties
|
||||||
|
colnr_T ul_textlen; // length of the line excluding NUL and any text
|
||||||
|
// properties
|
||||||
} undoline_T;
|
} undoline_T;
|
||||||
|
|
||||||
typedef struct u_entry u_entry_T;
|
typedef struct u_entry u_entry_T;
|
||||||
|
@ -149,7 +149,7 @@ func Test_undotree_bufnr()
|
|||||||
" Drop created windows
|
" Drop created windows
|
||||||
set ul&
|
set ul&
|
||||||
new
|
new
|
||||||
only!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_global_local_undolevels()
|
func Test_global_local_undolevels()
|
||||||
@ -193,6 +193,7 @@ func Test_global_local_undolevels()
|
|||||||
" Drop created windows
|
" Drop created windows
|
||||||
set ul&
|
set ul&
|
||||||
new
|
new
|
||||||
|
bw! one two
|
||||||
only!
|
only!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
@ -253,7 +254,7 @@ func Test_undo_del_chars()
|
|||||||
later 1h
|
later 1h
|
||||||
call assert_equal('123-abc', getline(1))
|
call assert_equal('123-abc', getline(1))
|
||||||
|
|
||||||
close!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_undolist()
|
func Test_undolist()
|
||||||
@ -274,7 +275,16 @@ func Test_undolist()
|
|||||||
call feedkeys('achange3\<Esc>', 'xt')
|
call feedkeys('achange3\<Esc>', 'xt')
|
||||||
let a = execute('undolist')
|
let a = execute('undolist')
|
||||||
call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
|
call assert_match("^\nnumber changes when *saved\n *2 *2 *.*\n *3 *2 .*$", a)
|
||||||
close!
|
|
||||||
|
" 3 save number
|
||||||
|
if has("persistent_undo")
|
||||||
|
setl undofile
|
||||||
|
w Xundolist.txt
|
||||||
|
defer delete('Xundolist.txt')
|
||||||
|
let lastline = execute('undolist')->split("\n")[-1]
|
||||||
|
call assert_match("ago 1", lastline)
|
||||||
|
endif
|
||||||
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_U_command()
|
func Test_U_command()
|
||||||
@ -286,7 +296,7 @@ func Test_U_command()
|
|||||||
call assert_equal('', getline(1))
|
call assert_equal('', getline(1))
|
||||||
norm! U
|
norm! U
|
||||||
call assert_equal('change1change2', getline(1))
|
call assert_equal('change1change2', getline(1))
|
||||||
close!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_undojoin()
|
func Test_undojoin()
|
||||||
@ -393,7 +403,7 @@ func Test_insert_expr()
|
|||||||
call feedkeys("u", 'x')
|
call feedkeys("u", 'x')
|
||||||
call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
|
call assert_equal(['a', 'b', 'c', '12', 'd'], getline(2, '$'))
|
||||||
|
|
||||||
close!
|
bw!
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_undofile_earlier()
|
func Test_undofile_earlier()
|
||||||
|
65
src/undo.c
65
src/undo.c
@ -361,6 +361,7 @@ u_save_line(undoline_T *ul, linenr_T lnum)
|
|||||||
{
|
{
|
||||||
char_u *line = ml_get(lnum);
|
char_u *line = ml_get(lnum);
|
||||||
|
|
||||||
|
ul->ul_textlen = ml_get_len(lnum);
|
||||||
if (curbuf->b_ml.ml_line_len == 0)
|
if (curbuf->b_ml.ml_line_len == 0)
|
||||||
{
|
{
|
||||||
ul->ul_len = 1;
|
ul->ul_len = 1;
|
||||||
@ -793,14 +794,10 @@ u_compute_hash(char_u *hash)
|
|||||||
{
|
{
|
||||||
context_sha256_T ctx;
|
context_sha256_T ctx;
|
||||||
linenr_T lnum;
|
linenr_T lnum;
|
||||||
char_u *p;
|
|
||||||
|
|
||||||
sha256_start(&ctx);
|
sha256_start(&ctx);
|
||||||
for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
|
for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
|
||||||
{
|
sha256_update(&ctx, ml_get(lnum), (UINT32_T)(ml_get_len(lnum) + 1));
|
||||||
p = ml_get(lnum);
|
|
||||||
sha256_update(&ctx, p, (UINT32_T)(STRLEN(p) + 1));
|
|
||||||
}
|
|
||||||
sha256_finish(&ctx, hash);
|
sha256_finish(&ctx, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -820,8 +817,10 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
|||||||
char_u *undo_file_name = NULL;
|
char_u *undo_file_name = NULL;
|
||||||
int dir_len;
|
int dir_len;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
size_t plen;
|
||||||
stat_T st;
|
stat_T st;
|
||||||
char_u *ffname = buf_ffname;
|
char_u *ffname = buf_ffname;
|
||||||
|
size_t ffnamelen;
|
||||||
#ifdef HAVE_READLINK
|
#ifdef HAVE_READLINK
|
||||||
char_u fname_buf[MAXPATHL];
|
char_u fname_buf[MAXPATHL];
|
||||||
#endif
|
#endif
|
||||||
@ -836,6 +835,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
|||||||
ffname = fname_buf;
|
ffname = fname_buf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
ffnamelen = STRLEN(ffname);
|
||||||
// Loop over 'undodir'. When reading find the first file that exists.
|
// Loop over 'undodir'. When reading find the first file that exists.
|
||||||
// When not reading use the first directory that exists or ".".
|
// When not reading use the first directory that exists or ".".
|
||||||
dirp = p_udir;
|
dirp = p_udir;
|
||||||
@ -846,23 +846,24 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
|||||||
{
|
{
|
||||||
// Use same directory as the ffname,
|
// Use same directory as the ffname,
|
||||||
// "dir/name" -> "dir/.name.un~"
|
// "dir/name" -> "dir/.name.un~"
|
||||||
undo_file_name = vim_strnsave(ffname, STRLEN(ffname) + 5);
|
undo_file_name = vim_strnsave(ffname, ffnamelen + 5);
|
||||||
if (undo_file_name == NULL)
|
if (undo_file_name == NULL)
|
||||||
break;
|
break;
|
||||||
p = gettail(undo_file_name);
|
p = gettail(undo_file_name);
|
||||||
|
plen = (size_t)(ffnamelen - (p - undo_file_name));
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
// VMS can not handle more than one dot in the filenames
|
// VMS can not handle more than one dot in the filenames
|
||||||
// use "dir/name" -> "dir/_un_name" - add _un_
|
// use "dir/name" -> "dir/_un_name" - add _un_
|
||||||
// at the beginning to keep the extension
|
// at the beginning to keep the extension
|
||||||
mch_memmove(p + 4, p, STRLEN(p) + 1);
|
mch_memmove(p + 4, p, plen + 1);
|
||||||
mch_memmove(p, "_un_", 4);
|
mch_memmove(p, "_un_", 4);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// Use same directory as the ffname,
|
// Use same directory as the ffname,
|
||||||
// "dir/name" -> "dir/.name.un~"
|
// "dir/name" -> "dir/.name.un~"
|
||||||
mch_memmove(p + 1, p, STRLEN(p) + 1);
|
mch_memmove(p + 1, p, plen + 1);
|
||||||
*p = '.';
|
*p = '.';
|
||||||
STRCAT(p, ".un~");
|
STRCPY(p + plen + 1, ".un~");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -872,7 +873,7 @@ u_get_undo_file_name(char_u *buf_ffname, int reading)
|
|||||||
{
|
{
|
||||||
if (munged_name == NULL)
|
if (munged_name == NULL)
|
||||||
{
|
{
|
||||||
munged_name = vim_strsave(ffname);
|
munged_name = vim_strnsave(ffname, ffnamelen);
|
||||||
if (munged_name == NULL)
|
if (munged_name == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (p = munged_name; *p != NUL; MB_PTR_ADV(p))
|
for (p = munged_name; *p != NUL; MB_PTR_ADV(p))
|
||||||
@ -1189,7 +1190,6 @@ read_string_decrypt(bufinfo_T *bi, int len)
|
|||||||
static int
|
static int
|
||||||
serialize_header(bufinfo_T *bi, char_u *hash)
|
serialize_header(bufinfo_T *bi, char_u *hash)
|
||||||
{
|
{
|
||||||
long len;
|
|
||||||
buf_T *buf = bi->bi_buf;
|
buf_T *buf = bi->bi_buf;
|
||||||
FILE *fp = bi->bi_fp;
|
FILE *fp = bi->bi_fp;
|
||||||
char_u time_buf[8];
|
char_u time_buf[8];
|
||||||
@ -1205,6 +1205,7 @@ serialize_header(bufinfo_T *bi, char_u *hash)
|
|||||||
{
|
{
|
||||||
char_u *header;
|
char_u *header;
|
||||||
int header_len;
|
int header_len;
|
||||||
|
long len;
|
||||||
|
|
||||||
undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2);
|
undo_write_bytes(bi, (long_u)UF_VERSION_CRYPT, 2);
|
||||||
bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf),
|
bi->bi_state = crypt_create_for_writing(crypt_get_method_nr(buf),
|
||||||
@ -1244,11 +1245,9 @@ serialize_header(bufinfo_T *bi, char_u *hash)
|
|||||||
|
|
||||||
// buffer-specific data
|
// buffer-specific data
|
||||||
undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4);
|
undo_write_bytes(bi, (long_u)buf->b_ml.ml_line_count, 4);
|
||||||
len = buf->b_u_line_ptr.ul_line == NULL
|
undo_write_bytes(bi, (long_u)buf->b_u_line_ptr.ul_textlen, 4);
|
||||||
? 0L : (long)STRLEN(buf->b_u_line_ptr.ul_line);
|
if (buf->b_u_line_ptr.ul_textlen > 0 && fwrite_crypt(bi, buf->b_u_line_ptr.ul_line,
|
||||||
undo_write_bytes(bi, (long_u)len, 4);
|
(size_t)buf->b_u_line_ptr.ul_textlen) == FAIL)
|
||||||
if (len > 0 && fwrite_crypt(bi, buf->b_u_line_ptr.ul_line, (size_t)len)
|
|
||||||
== FAIL)
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4);
|
undo_write_bytes(bi, (long_u)buf->b_u_line_lnum, 4);
|
||||||
undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4);
|
undo_write_bytes(bi, (long_u)buf->b_u_line_colnr, 4);
|
||||||
@ -1415,7 +1414,6 @@ serialize_uep(
|
|||||||
u_entry_T *uep)
|
u_entry_T *uep)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
size_t len;
|
|
||||||
|
|
||||||
undo_write_bytes(bi, (long_u)uep->ue_top, 4);
|
undo_write_bytes(bi, (long_u)uep->ue_top, 4);
|
||||||
undo_write_bytes(bi, (long_u)uep->ue_bot, 4);
|
undo_write_bytes(bi, (long_u)uep->ue_bot, 4);
|
||||||
@ -1425,10 +1423,10 @@ serialize_uep(
|
|||||||
{
|
{
|
||||||
// Text is written without the text properties, since we cannot restore
|
// Text is written without the text properties, since we cannot restore
|
||||||
// the text property types.
|
// the text property types.
|
||||||
len = STRLEN(uep->ue_array[i].ul_line);
|
if (undo_write_bytes(bi, (long_u)uep->ue_array[i].ul_textlen, 4) == FAIL)
|
||||||
if (undo_write_bytes(bi, (long_u)len, 4) == FAIL)
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
if (len > 0 && fwrite_crypt(bi, uep->ue_array[i].ul_line, len) == FAIL)
|
if (uep->ue_array[i].ul_textlen > 0
|
||||||
|
&& fwrite_crypt(bi, uep->ue_array[i].ul_line, uep->ue_array[i].ul_textlen) == FAIL)
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@ -1484,6 +1482,7 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
|
|||||||
}
|
}
|
||||||
array[i].ul_line = line;
|
array[i].ul_line = line;
|
||||||
array[i].ul_len = line_len + 1;
|
array[i].ul_len = line_len + 1;
|
||||||
|
array[i].ul_textlen = line_len;
|
||||||
}
|
}
|
||||||
return uep;
|
return uep;
|
||||||
}
|
}
|
||||||
@ -1862,6 +1861,7 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name UNUSED)
|
|||||||
|
|
||||||
CLEAR_FIELD(bi);
|
CLEAR_FIELD(bi);
|
||||||
line_ptr.ul_len = 0;
|
line_ptr.ul_len = 0;
|
||||||
|
line_ptr.ul_textlen = 0;
|
||||||
line_ptr.ul_line = NULL;
|
line_ptr.ul_line = NULL;
|
||||||
|
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
@ -1986,6 +1986,7 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name UNUSED)
|
|||||||
{
|
{
|
||||||
line_ptr.ul_line = read_string_decrypt(&bi, str_len);
|
line_ptr.ul_line = read_string_decrypt(&bi, str_len);
|
||||||
line_ptr.ul_len = str_len + 1;
|
line_ptr.ul_len = str_len + 1;
|
||||||
|
line_ptr.ul_textlen = str_len;
|
||||||
}
|
}
|
||||||
line_lnum = (linenr_T)undo_read_4c(&bi);
|
line_lnum = (linenr_T)undo_read_4c(&bi);
|
||||||
line_colnr = (colnr_T)undo_read_4c(&bi);
|
line_colnr = (colnr_T)undo_read_4c(&bi);
|
||||||
@ -3098,7 +3099,7 @@ ex_undolist(exarg_T *eap UNUSED)
|
|||||||
int mark;
|
int mark;
|
||||||
int nomark;
|
int nomark;
|
||||||
int changes = 1;
|
int changes = 1;
|
||||||
int i;
|
int len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1: walk the tree to find all leafs, put the info in "ga".
|
* 1: walk the tree to find all leafs, put the info in "ga".
|
||||||
@ -3117,18 +3118,20 @@ ex_undolist(exarg_T *eap UNUSED)
|
|||||||
{
|
{
|
||||||
if (ga_grow(&ga, 1) == FAIL)
|
if (ga_grow(&ga, 1) == FAIL)
|
||||||
break;
|
break;
|
||||||
vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ",
|
len = vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7d ",
|
||||||
uhp->uh_seq, changes);
|
uhp->uh_seq, changes);
|
||||||
add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
|
add_time(IObuff + len, IOSIZE - len, uhp->uh_time);
|
||||||
uhp->uh_time);
|
|
||||||
|
// we have to call STRLEN() here because add_time() does not report
|
||||||
|
// the number of characters added.
|
||||||
|
len += STRLEN(IObuff + len);
|
||||||
if (uhp->uh_save_nr > 0)
|
if (uhp->uh_save_nr > 0)
|
||||||
{
|
{
|
||||||
while (STRLEN(IObuff) < 33)
|
int n = (len >= 33) ? 0 : 33 - len;
|
||||||
STRCAT(IObuff, " ");
|
|
||||||
vim_snprintf_add((char *)IObuff, IOSIZE,
|
len += vim_snprintf((char *)IObuff + len, IOSIZE - len, "%*.*s %3ld", n, n, " ", uhp->uh_save_nr);
|
||||||
" %3ld", uhp->uh_save_nr);
|
|
||||||
}
|
}
|
||||||
((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
|
((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strnsave(IObuff, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
uhp->uh_walk = mark;
|
uhp->uh_walk = mark;
|
||||||
@ -3175,6 +3178,8 @@ ex_undolist(exarg_T *eap UNUSED)
|
|||||||
msg(_("Nothing to undo"));
|
msg(_("Nothing to undo"));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
sort_strings((char_u **)ga.ga_data, ga.ga_len);
|
sort_strings((char_u **)ga.ga_data, ga.ga_len);
|
||||||
|
|
||||||
msg_start();
|
msg_start();
|
||||||
@ -3481,6 +3486,7 @@ u_clearall(buf_T *buf)
|
|||||||
buf->b_u_numhead = 0;
|
buf->b_u_numhead = 0;
|
||||||
buf->b_u_line_ptr.ul_line = NULL;
|
buf->b_u_line_ptr.ul_line = NULL;
|
||||||
buf->b_u_line_ptr.ul_len = 0;
|
buf->b_u_line_ptr.ul_len = 0;
|
||||||
|
buf->b_u_line_ptr.ul_textlen = 0;
|
||||||
buf->b_u_line_lnum = 0;
|
buf->b_u_line_lnum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3540,6 +3546,7 @@ u_clearline(void)
|
|||||||
|
|
||||||
VIM_CLEAR(curbuf->b_u_line_ptr.ul_line);
|
VIM_CLEAR(curbuf->b_u_line_ptr.ul_line);
|
||||||
curbuf->b_u_line_ptr.ul_len = 0;
|
curbuf->b_u_line_ptr.ul_len = 0;
|
||||||
|
curbuf->b_u_line_ptr.ul_textlen = 0;
|
||||||
curbuf->b_u_line_lnum = 0;
|
curbuf->b_u_line_lnum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
/**/
|
||||||
|
843,
|
||||||
/**/
|
/**/
|
||||||
842,
|
842,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user