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.

Raspunde prin e-mail lui