Patch 8.2.4518
Problem: The binary tag search feature is always enabled.
Solution: Remove the #ifdefs. Add a few more tests. (Yegappan Lakshmanan,
closes #9893)
Files: src/evalfunc.c, src/feature.h, src/tag.c, src/version.c,
src/testdir/test_tagjump.vim, src/testdir/test_taglist.vim
*** ../vim-8.2.4517/src/evalfunc.c 2022-02-23 21:03:28.913442583 +0000
--- src/evalfunc.c 2022-03-06 14:07:16.086379968 +0000
***************
*** 4382,4388 ****
if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s))
|| (is_funcref && trans_name == NULL))
! semsg(_(e_invalid_argument_str), use_string ?
tv_get_string(&argvars[0]) : s);
// Don't check an autoload name for existence here.
else if (trans_name != NULL && (is_funcref
? find_func(trans_name, is_global) == NULL
--- 4382,4389 ----
if (s == NULL || *s == NUL || (use_string && VIM_ISDIGIT(*s))
|| (is_funcref && trans_name == NULL))
! semsg(_(e_invalid_argument_str),
! use_string ? tv_get_string(&argvars[0]) : s);
// Don't check an autoload name for existence here.
else if (trans_name != NULL && (is_funcref
? find_func(trans_name, is_global) == NULL
***************
*** 6101,6113 ****
0
#endif
},
! {"tag_binary",
! #ifdef FEAT_TAG_BINS
! 1
! #else
! 0
! #endif
! },
{"tcl",
#if defined(FEAT_TCL) && !defined(DYNAMIC_TCL)
1
--- 6102,6108 ----
0
#endif
},
! {"tag_binary", 1}, // graduated feature
{"tcl",
#if defined(FEAT_TCL) && !defined(DYNAMIC_TCL)
1
*** ../vim-8.2.4517/src/feature.h 2022-02-23 18:07:34.361914993 +0000
--- src/feature.h 2022-03-06 14:07:16.086379968 +0000
***************
*** 249,259 ****
#endif
/*
- * +tag_binary Can use a binary search for the tags file.
- */
- #define FEAT_TAG_BINS
-
- /*
* +cscope Unix only: Cscope support.
*/
#if defined(UNIX) && defined(FEAT_BIG) && !defined(FEAT_CSCOPE) &&
!defined(MACOS_X)
--- 249,254 ----
*** ../vim-8.2.4517/src/tag.c 2022-03-05 14:35:07.319171786 +0000
--- src/tag.c 2022-03-06 14:07:16.086379968 +0000
***************
*** 1270,1276 ****
msg_puts("\n>");
}
- #ifdef FEAT_TAG_BINS
/*
* Compare two strings, for length "len", ignoring case the ASCII way.
* return 0 for match, < 0 for smaller, > 0 for bigger
--- 1270,1275 ----
***************
*** 1294,1300 ****
}
return 0; // strings match
}
- #endif
/*
* Structure to hold info about the tag pattern being used.
--- 1293,1298 ----
***************
*** 1592,1600 ****
int did_open; // did open a tag file
int mincount; // MAXCOL: find all matches
// other: minimal number of matches
- #ifdef FEAT_TAG_BINS
int linear; // do a linear search
- #endif
char_u *lbuf; // line buffer
int lbuf_size; // length of lbuf
#ifdef FEAT_EMACS_TAGS
--- 1590,1596 ----
***************
*** 1960,1969 ****
return FALSE;
// Read header line.
- #ifdef FEAT_TAG_BINS
if (STRNCMP(st->lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
*sorted_file = st->lbuf[18];
- #endif
if (STRNCMP(st->lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
{
// Prepare to convert every line from the specified
--- 1956,1963 ----
***************
*** 2264,2286 ****
int help_pri = 0;
char_u help_lang[3] = ""; // lang of current tags file
#endif
- #ifdef FEAT_TAG_BINS
int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value
off_T filesize;
int tagcmp;
off_T offset;
- #endif
enum
{
TS_START, // at start of file
! TS_LINEAR // linear searching forward, till EOF
! #ifdef FEAT_TAG_BINS
! , TS_BINARY, // binary searching
TS_SKIP_BACK, // skipping backwards
TS_STEP_FORWARD // stepping forwards
- #endif
} state; // Current search state
- #ifdef FEAT_TAG_BINS
struct tag_search_info // Binary search file offsets
{
off_T low_offset; // offset for first char of first line that
--- 2258,2275 ----
int help_pri = 0;
char_u help_lang[3] = ""; // lang of current tags file
#endif
int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value
off_T filesize;
int tagcmp;
off_T offset;
enum
{
TS_START, // at start of file
! TS_LINEAR, // linear searching forward, till EOF
! TS_BINARY, // binary searching
TS_SKIP_BACK, // skipping backwards
TS_STEP_FORWARD // stepping forwards
} state; // Current search state
struct tag_search_info // Binary search file offsets
{
off_T low_offset; // offset for first char of first line that
***************
*** 2293,2299 ****
int low_char; // first char at low_offset
int high_char; // first char at high_offset
} search_info;
- #endif
int cmplen;
int match; // matches
--- 2282,2287 ----
***************
*** 2305,2315 ****
hash_T hash = 0;
- #ifdef FEAT_TAG_BINS
int sort_error = FALSE; // tags file not sorted
int sortic = FALSE; // tag file sorted in
nocase
int noic = (flags & TAG_NOIC);
- #endif
int line_error = FALSE; // syntax error
int has_re = (flags & TAG_REGEXP); // regexp used
#ifdef FEAT_CSCOPE
--- 2293,2301 ----
***************
*** 2319,2329 ****
vimconv.vc_type = CONV_NONE;
- #ifdef FEAT_TAG_BINS
// This is only to avoid a compiler warning for using search_info
// uninitialised.
CLEAR_FIELD(search_info);
- #endif
// A file that doesn't exist is silently ignored. Only when not a
// single file is found, an error message is given (further on).
--- 2305,2313 ----
***************
*** 2359,2370 ****
// Read and parse the lines in the file one by one
for (;;)
{
- #ifdef FEAT_TAG_BINS
// check for CTRL-C typed, more often when jumping around
if (state == TS_BINARY || state == TS_SKIP_BACK)
line_breakcheck();
else
- #endif
fast_breakcheck();
if ((flags & TAG_INS_COMP)) // Double brackets for gcc
ins_compl_check_keys(30, FALSE);
--- 2343,2352 ----
***************
*** 2382,2388 ****
}
if (st->get_searchpat)
goto line_read_in;
- #ifdef FEAT_TAG_BINS
// For binary search: compute the next offset to use.
if (state == TS_BINARY)
{
--- 2364,2369 ----
***************
*** 2449,2455 ****
* Not jumping around in the file: Read the next line.
*/
else
- #endif
{
// skip empty and blank lines
do
--- 2430,2435 ----
***************
*** 2460,2468 ****
else
#endif
{
- #ifdef FEAT_TAG_BINS
search_info.curr_offset = vim_ftell(fp);
- #endif
eof = vim_fgets(st->lbuf, st->lbuf_size, fp);
}
} while (!eof && vim_isblankline(st->lbuf));
--- 2440,2446 ----
***************
*** 2525,2531 ****
// Headers ends.
- #ifdef FEAT_TAG_BINS
/*
* When there is no tag head, or ignoring case, need to do a
* linear search.
--- 2503,2508 ----
***************
*** 2561,2571 ****
st->linear = TRUE;
state = TS_LINEAR;
}
- #else
- state = TS_LINEAR;
- #endif
- #ifdef FEAT_TAG_BINS
// When starting a binary search, get the size of the file and
// compute the first offset.
if (state == TS_BINARY)
--- 2538,2544 ----
***************
*** 2591,2597 ****
}
continue;
}
- #endif
}
parse_line:
--- 2564,2569 ----
***************
*** 2615,2628 ****
return FAIL;
}
- #ifdef FEAT_TAG_BINS
if (state == TS_STEP_FORWARD)
// Seek to the same position to read the same line again
vim_fseek(fp, search_info.curr_offset, SEEK_SET);
// this will try the same thing again, make sure the offset is
// different
search_info.curr_offset = 0;
- #endif
continue;
}
--- 2587,2598 ----
***************
*** 2659,2665 ****
else if (state == TS_LINEAR && st->orgpat.headlen != cmplen)
continue;
- #ifdef FEAT_TAG_BINS
if (state == TS_BINARY)
{
/*
--- 2629,2634 ----
***************
*** 2750,2756 ****
}
}
else
- #endif
// skip this match if it can't match
if (MB_STRNICMP(tagp.tagname, st->orgpat.head, cmplen) != 0)
continue;
--- 2719,2724 ----
***************
*** 2874,2887 ****
if (vimconv.vc_type != CONV_NONE)
convert_setup(&vimconv, NULL, NULL);
- #ifdef FEAT_TAG_BINS
tag_file_sorted = NUL;
if (sort_error)
{
semsg(_(e_tags_file_not_sorted_str), st->tag_fname);
sort_error = FALSE;
}
- #endif
/*
* Stop searching if sufficient tags have been found.
--- 2842,2853 ----
***************
*** 2983,2991 ****
tagname_T tn; // info for get_tagfname()
int first_file; // trying first tag file
int retval = FAIL; // return value
- #ifdef FEAT_TAG_BINS
int round;
- #endif
int save_emsg_off;
--- 2949,2955 ----
***************
*** 2995,3004 ****
char_u *saved_pat = NULL; // copy of pat[]
#endif
- #ifdef FEAT_TAG_BINS
int findall = (mincount == MAXCOL || mincount == TAG_MANY);
// find all matching tags
- #endif
int has_re = (flags & TAG_REGEXP); // regexp used
int noic = (flags & TAG_NOIC);
#ifdef FEAT_CSCOPE
--- 2959,2966 ----
***************
*** 3101,3115 ****
* When the tag file is case-fold sorted, it is either one or the other.
* Only ignore case when TAG_NOIC not used or 'ignorecase' set.
*/
- #ifdef FEAT_TAG_BINS
st.orgpat.regmatch.rm_ic = ((p_ic || !noic)
&& (findall || st.orgpat.headlen == 0 || !p_tbs));
for (round = 1; round <= 2; ++round)
{
st.linear = (st.orgpat.headlen == 0 || !p_tbs || round == 2);
- #else
- st.orgpat.regmatch.rm_ic = (p_ic || !noic);
- #endif
/*
* Try tag file names from tags option one by one.
--- 3063,3073 ----
***************
*** 3139,3145 ****
#endif
tagname_free(&tn);
- #ifdef FEAT_TAG_BINS
// stop searching when already did a linear search, or when TAG_NOIC
// used, and 'ignorecase' not set or already did case-ignore search
if (st.stop_searching || st.linear || (!p_ic && noic) ||
--- 3097,3102 ----
***************
*** 3153,3159 ****
// try another time while ignoring case
st.orgpat.regmatch.rm_ic = TRUE;
}
- #endif
if (!st.stop_searching)
{
--- 3110,3115 ----
*** ../vim-8.2.4517/src/version.c 2022-03-06 14:01:48.179250403 +0000
--- src/version.c 2022-03-06 14:08:55.406125125 +0000
***************
*** 590,600 ****
#if defined(USE_SYSTEM) && defined(UNIX)
"+system()",
#endif
- #ifdef FEAT_TAG_BINS
"+tag_binary",
- #else
- "-tag_binary",
- #endif
"-tag_old_static",
"-tag_any_white",
#ifdef FEAT_TCL
--- 590,596 ----
*** ../vim-8.2.4517/src/testdir/test_tagjump.vim 2022-03-05
14:35:07.319171786 +0000
--- src/testdir/test_tagjump.vim 2022-03-06 14:07:16.086379968 +0000
***************
*** 1503,1506 ****
--- 1503,1579 ----
set tags&
endfunc
+ " Test for 'tagbsearch' (binary search)
+ func Test_tagbsearch()
+ " If a tags file header says the tags are sorted, but the tags are actually
+ " unsorted, then binary search should fail and linear search should work.
+ call writefile([
+ \ "!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "!_TAG_FILE_SORTED\t1\t/0=unsorted, 1=sorted, 2=foldcase/",
+ \ "third\tXfoo\t3",
+ \ "second\tXfoo\t2",
+ \ "first\tXfoo\t1"],
+ \ 'Xtags')
+ set tags=Xtags
+ let code =<< trim [CODE]
+ int first() {}
+ int second() {}
+ int third() {}
+ [CODE]
+ call writefile(code, 'Xfoo')
+
+ enew
+ set tagbsearch
+ call assert_fails('tag first', 'E426:')
+ call assert_equal('', bufname())
+ call assert_fails('tag second', 'E426:')
+ call assert_equal('', bufname())
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ set notagbsearch
+ tag first
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(1, line('.'))
+ enew
+ tag second
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(2, line('.'))
+ enew
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ " If a tags file header says the tags are unsorted, but the tags are
+ " actually sorted, then binary search should work.
+ call writefile([
+ \ "!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted, 2=foldcase/",
+ \ "first\tXfoo\t1",
+ \ "second\tXfoo\t2",
+ \ "third\tXfoo\t3"],
+ \ 'Xtags')
+
+ set tagbsearch
+ tag first
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(1, line('.'))
+ enew
+ tag second
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(2, line('.'))
+ enew
+ tag third
+ call assert_equal('Xfoo', bufname())
+ call assert_equal(3, line('.'))
+ %bw!
+
+ call delete('Xtags')
+ call delete('Xfoo')
+ set tags& tagbsearch&
+ endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4517/src/testdir/test_taglist.vim 2021-12-10
20:15:11.697972271 +0000
--- src/testdir/test_taglist.vim 2022-03-06 14:07:16.086379968 +0000
***************
*** 37,42 ****
--- 37,48 ----
call assert_equal('d', cmd[0]['kind'])
call assert_equal('call cursor(3, 4)', cmd[0]['cmd'])
+ " Use characters with value > 127 in the tag extra field.
+ call writefile([
+ \ "vFoo\tXfoo\t4" .. ';"' .. "\ttypename:int\ta£££\tv",
+ \ ], 'Xtags')
+ call assert_equal('v', taglist('vFoo')[0].kind)
+
call assert_fails("let l=taglist([])", 'E730:')
call delete('Xtags')
***************
*** 216,221 ****
--- 222,232 ----
endtry
call assert_true(caught_exception)
+ " no field after the filename for a tag
+ call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
+ \ "foo\tXfile"], 'Xtags')
+ call assert_fails("echo taglist('foo')", 'E431:')
+
set tags&
call delete('Xtags')
endfunc
*** ../vim-8.2.4517/src/version.c 2022-03-06 14:01:48.179250403 +0000
--- src/version.c 2022-03-06 14:08:55.406125125 +0000
***************
*** 756,757 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 4518,
/**/
--
hundred-and-one symptoms of being an internet addict:
177. You log off of your system because it's time to go to work.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/20220306142804.7511D1C042A%40moolenaar.net.