summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2022-03-06 14:27:10 +0000
committerBram Moolenaar <Bram@vim.org>2022-03-06 14:27:10 +0000
commit655b734ee858e90dd8d28549b7704a71b25d30e7 (patch)
treea18d58d13ad674adfc569675fe1b7979b8fe3846
parent9eccee0e856e9fc77c343028b516dfe5df8fd1ed (diff)
downloadvim-git-655b734ee858e90dd8d28549b7704a71b25d30e7.tar.gz
patch 8.2.4518: the binary tag search feature is always enabledv8.2.4518
Problem: The binary tag search feature is always enabled. Solution: Remove the #ifdefs. Add a few more tests. (Yegappan Lakshmanan, closes #9893)
-rw-r--r--src/evalfunc.c11
-rw-r--r--src/feature.h5
-rw-r--r--src/tag.c48
-rw-r--r--src/testdir/test_tagjump.vim73
-rw-r--r--src/testdir/test_taglist.vim11
-rw-r--r--src/version.c6
6 files changed, 91 insertions, 63 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 1b9320036..39a2fd276 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -4382,7 +4382,8 @@ common_function(typval_T *argvars, typval_T *rettv, int is_funcref)
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);
+ 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,13 +6102,7 @@ f_has(typval_T *argvars, typval_T *rettv)
0
#endif
},
- {"tag_binary",
-#ifdef FEAT_TAG_BINS
- 1
-#else
- 0
-#endif
- },
+ {"tag_binary", 1}, // graduated feature
{"tcl",
#if defined(FEAT_TCL) && !defined(DYNAMIC_TCL)
1
diff --git a/src/feature.h b/src/feature.h
index 9564f8e10..0f5bf1e01 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -249,11 +249,6 @@
#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)
diff --git a/src/tag.c b/src/tag.c
index 76558cb9e..65723ed57 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -1270,7 +1270,6 @@ do_tags(exarg_T *eap UNUSED)
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
@@ -1294,7 +1293,6 @@ tag_strnicmp(char_u *s1, char_u *s2, size_t len)
}
return 0; // strings match
}
-#endif
/*
* Structure to hold info about the tag pattern being used.
@@ -1592,9 +1590,7 @@ typedef struct {
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
@@ -1960,10 +1956,8 @@ tags_file_hdr_parse(findtags_state_T *st, vimconv_T *vcp, int *sorted_file)
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
@@ -2264,23 +2258,18 @@ find_tags_in_file(
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_LINEAR, // linear searching forward, till EOF
+ 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
@@ -2293,7 +2282,6 @@ find_tags_in_file(
int low_char; // first char at low_offset
int high_char; // first char at high_offset
} search_info;
-#endif
int cmplen;
int match; // matches
@@ -2305,11 +2293,9 @@ find_tags_in_file(
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
@@ -2319,11 +2305,9 @@ find_tags_in_file(
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).
@@ -2359,12 +2343,10 @@ find_tags_in_file(
// 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);
@@ -2382,7 +2364,6 @@ find_tags_in_file(
}
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)
{
@@ -2449,7 +2430,6 @@ find_tags_in_file(
* Not jumping around in the file: Read the next line.
*/
else
-#endif
{
// skip empty and blank lines
do
@@ -2460,9 +2440,7 @@ find_tags_in_file(
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));
@@ -2525,7 +2503,6 @@ line_read_in:
// Headers ends.
-#ifdef FEAT_TAG_BINS
/*
* When there is no tag head, or ignoring case, need to do a
* linear search.
@@ -2561,11 +2538,7 @@ line_read_in:
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)
@@ -2591,7 +2564,6 @@ line_read_in:
}
continue;
}
-#endif
}
parse_line:
@@ -2615,14 +2587,12 @@ parse_line:
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;
}
@@ -2659,7 +2629,6 @@ parse_line:
else if (state == TS_LINEAR && st->orgpat.headlen != cmplen)
continue;
-#ifdef FEAT_TAG_BINS
if (state == TS_BINARY)
{
/*
@@ -2750,7 +2719,6 @@ parse_line:
}
}
else
-#endif
// skip this match if it can't match
if (MB_STRNICMP(tagp.tagname, st->orgpat.head, cmplen) != 0)
continue;
@@ -2874,14 +2842,12 @@ parse_line:
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.
@@ -2983,9 +2949,7 @@ find_tags(
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;
@@ -2995,10 +2959,8 @@ find_tags(
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
@@ -3101,15 +3063,11 @@ find_tags(
* 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.
@@ -3139,7 +3097,6 @@ find_tags(
#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) ||
@@ -3153,7 +3110,6 @@ find_tags(
// try another time while ignoring case
st.orgpat.regmatch.rm_ic = TRUE;
}
-#endif
if (!st.stop_searching)
{
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index 95a3c3113..95652ef65 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -1503,4 +1503,77 @@ func Test_stag_close_window_on_error()
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
diff --git a/src/testdir/test_taglist.vim b/src/testdir/test_taglist.vim
index 3ba5ec094..04ca02dec 100644
--- a/src/testdir/test_taglist.vim
+++ b/src/testdir/test_taglist.vim
@@ -37,6 +37,12 @@ func Test_taglist()
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,6 +222,11 @@ func Test_format_error()
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
diff --git a/src/version.c b/src/version.c
index 5e7d57091..771530ada 100644
--- a/src/version.c
+++ b/src/version.c
@@ -590,11 +590,7 @@ static char *(features[]) =
#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
@@ -755,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4518,
+/**/
4517,
/**/
4516,