vim-patch:8.1.2269: tags file with very long line stops using binary search

Problem:    Tags file with very long line stops using binary search.
Solution:   Reallocate the buffer if needed.
dc9ef26845
This commit is contained in:
Jan Edmund Lazo 2019-11-20 22:08:01 -05:00
parent 0f29deec80
commit 970329ff8d
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
2 changed files with 41 additions and 28 deletions

View File

@ -1659,12 +1659,9 @@ find_tags(
break; /* End the binary search without a match. */
else
search_info.curr_offset = offset;
}
/*
* Skipping back (after a match during binary search).
*/
else if (state == TS_SKIP_BACK) {
search_info.curr_offset -= LSIZE * 2;
} else if (state == TS_SKIP_BACK) {
// Skipping back (after a match during binary search).
search_info.curr_offset -= lbuf_size * 2;
if (search_info.curr_offset < 0) {
search_info.curr_offset = 0;
rewind(fp);
@ -1680,7 +1677,7 @@ find_tags(
/* Adjust the search file offset to the correct position */
search_info.curr_offset_used = search_info.curr_offset;
vim_fseek(fp, search_info.curr_offset, SEEK_SET);
eof = vim_fgets(lbuf, LSIZE, fp);
eof = vim_fgets(lbuf, lbuf_size, fp);
if (!eof && search_info.curr_offset != 0) {
/* The explicit cast is to work around a bug in gcc 3.4.2
* (repeated below). */
@ -1690,12 +1687,12 @@ find_tags(
vim_fseek(fp, search_info.low_offset, SEEK_SET);
search_info.curr_offset = search_info.low_offset;
}
eof = vim_fgets(lbuf, LSIZE, fp);
eof = vim_fgets(lbuf, lbuf_size, fp);
}
/* skip empty and blank lines */
while (!eof && vim_isblankline(lbuf)) {
search_info.curr_offset = vim_ftell(fp);
eof = vim_fgets(lbuf, LSIZE, fp);
eof = vim_fgets(lbuf, lbuf_size, fp);
}
if (eof) {
/* Hit end of file. Skip backwards. */
@ -1711,10 +1708,9 @@ find_tags(
else {
/* skip empty and blank lines */
do {
if (use_cscope)
eof = cs_fgets(lbuf, LSIZE);
else
eof = vim_fgets(lbuf, LSIZE, fp);
eof = use_cscope
? cs_fgets(lbuf, lbuf_size)
: vim_fgets(lbuf, lbuf_size, fp);
} while (!eof && vim_isblankline(lbuf));
if (eof) {
@ -1839,19 +1835,14 @@ parse_line:
// When the line is too long the NUL will not be in the
// last-but-one byte (see vim_fgets()).
// Has been reported for Mozilla JS with extremely long names.
// In that case we can't parse it and we ignore the line.
if (lbuf[LSIZE - 2] != NUL && !use_cscope) {
if (p_verbose >= 5) {
verbose_enter();
MSG(_("Ignoring long line in tags file"));
verbose_leave();
}
if (state != TS_LINEAR) {
// Avoid getting stuck.
linear = true;
state = TS_LINEAR;
vim_fseek(fp, search_info.low_offset, SEEK_SET);
}
// In that case we need to increase lbuf_size.
if (lbuf[lbuf_size - 2] != NUL && !use_cscope) {
lbuf_size *= 2;
xfree(lbuf);
lbuf = xmalloc(lbuf_size);
// this will try the same thing again, make sure the offset is
// different
search_info.curr_offset = 0;
continue;
}
@ -2654,6 +2645,9 @@ static int jumpto_tag(
str = tagp.command;
for (pbuf_end = pbuf; *str && *str != '\n' && *str != '\r'; ) {
*pbuf_end++ = *str++;
if (pbuf_end - pbuf + 1 >= LSIZE) {
break;
}
}
*pbuf_end = NUL;

View File

@ -449,7 +449,8 @@ func Test_tag_line_toolong()
call assert_report(v:exception)
catch /.*/
endtry
call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1])
call writefile([
\ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML'
\ ], 'Xtags')
@ -460,8 +461,26 @@ func Test_tag_line_toolong()
call assert_report(v:exception)
catch /.*/
endtry
call assert_equal('Ignoring long line in tags file', split(execute('messages'), '\n')[-1])
call assert_equal('Searching tags file Xtags', split(execute('messages'), '\n')[-1])
" binary search works in file with long line
call writefile([
\ 'asdfasfd nowhere 16',
\ 'foobar Xsomewhere 3; " 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567',
\ 'zasdfasfd nowhere 16',
\ ], 'Xtags')
call writefile([
\ 'one',
\ 'two',
\ 'trhee',
\ 'four',
\ ], 'Xsomewhere')
tag foobar
call assert_equal('Xsomewhere', expand('%'))
call assert_equal(3, getcurpos()[1])
call delete('Xtags')
call delete('Xsomewhere')
set tags&
let &verbose = old_vbs
endfunc