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

View File

@ -449,7 +449,8 @@ func Test_tag_line_toolong()
call assert_report(v:exception) call assert_report(v:exception)
catch /.*/ catch /.*/
endtry 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([ call writefile([
\ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML' \ '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567 django/contrib/admin/templates/admin/edit_inline/stacked.html 16;" j line:16 language:HTML'
\ ], 'Xtags') \ ], 'Xtags')
@ -460,8 +461,26 @@ func Test_tag_line_toolong()
call assert_report(v:exception) call assert_report(v:exception)
catch /.*/ catch /.*/
endtry 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('Xtags')
call delete('Xsomewhere')
set tags& set tags&
let &verbose = old_vbs let &verbose = old_vbs
endfunc endfunc