comparison src/tag.c @ 18550:90e5812af76b v8.1.2269

patch 8.1.2269: tags file with very long line stops using binary search Commit: https://github.com/vim/vim/commit/dc9ef26845c6bf5ba63bfa8d00fc8a9bdc3b2de5 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Nov 7 23:08:42 2019 +0100 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.
author Bram Moolenaar <Bram@vim.org>
date Thu, 07 Nov 2019 23:15:04 +0100
parents 34d5cd432cac
children 60c46cd053db
comparison
equal deleted inserted replaced
18549:8ce88501264f 18550:90e5812af76b
1935 /* 1935 /*
1936 * Skipping back (after a match during binary search). 1936 * Skipping back (after a match during binary search).
1937 */ 1937 */
1938 else if (state == TS_SKIP_BACK) 1938 else if (state == TS_SKIP_BACK)
1939 { 1939 {
1940 search_info.curr_offset -= LSIZE * 2; 1940 search_info.curr_offset -= lbuf_size * 2;
1941 if (search_info.curr_offset < 0) 1941 if (search_info.curr_offset < 0)
1942 { 1942 {
1943 search_info.curr_offset = 0; 1943 search_info.curr_offset = 0;
1944 rewind(fp); 1944 rewind(fp);
1945 state = TS_STEP_FORWARD; 1945 state = TS_STEP_FORWARD;
1953 if (state == TS_BINARY || state == TS_SKIP_BACK) 1953 if (state == TS_BINARY || state == TS_SKIP_BACK)
1954 { 1954 {
1955 /* Adjust the search file offset to the correct position */ 1955 /* Adjust the search file offset to the correct position */
1956 search_info.curr_offset_used = search_info.curr_offset; 1956 search_info.curr_offset_used = search_info.curr_offset;
1957 vim_fseek(fp, search_info.curr_offset, SEEK_SET); 1957 vim_fseek(fp, search_info.curr_offset, SEEK_SET);
1958 eof = vim_fgets(lbuf, LSIZE, fp); 1958 eof = vim_fgets(lbuf, lbuf_size, fp);
1959 if (!eof && search_info.curr_offset != 0) 1959 if (!eof && search_info.curr_offset != 0)
1960 { 1960 {
1961 /* The explicit cast is to work around a bug in gcc 3.4.2 1961 /* The explicit cast is to work around a bug in gcc 3.4.2
1962 * (repeated below). */ 1962 * (repeated below). */
1963 search_info.curr_offset = vim_ftell(fp); 1963 search_info.curr_offset = vim_ftell(fp);
1965 { 1965 {
1966 /* oops, gone a bit too far; try from low offset */ 1966 /* oops, gone a bit too far; try from low offset */
1967 vim_fseek(fp, search_info.low_offset, SEEK_SET); 1967 vim_fseek(fp, search_info.low_offset, SEEK_SET);
1968 search_info.curr_offset = search_info.low_offset; 1968 search_info.curr_offset = search_info.low_offset;
1969 } 1969 }
1970 eof = vim_fgets(lbuf, LSIZE, fp); 1970 eof = vim_fgets(lbuf, lbuf_size, fp);
1971 } 1971 }
1972 /* skip empty and blank lines */ 1972 /* skip empty and blank lines */
1973 while (!eof && vim_isblankline(lbuf)) 1973 while (!eof && vim_isblankline(lbuf))
1974 { 1974 {
1975 search_info.curr_offset = vim_ftell(fp); 1975 search_info.curr_offset = vim_ftell(fp);
1976 eof = vim_fgets(lbuf, LSIZE, fp); 1976 eof = vim_fgets(lbuf, lbuf_size, fp);
1977 } 1977 }
1978 if (eof) 1978 if (eof)
1979 { 1979 {
1980 /* Hit end of file. Skip backwards. */ 1980 /* Hit end of file. Skip backwards. */
1981 state = TS_SKIP_BACK; 1981 state = TS_SKIP_BACK;
1994 /* skip empty and blank lines */ 1994 /* skip empty and blank lines */
1995 do 1995 do
1996 { 1996 {
1997 #ifdef FEAT_CSCOPE 1997 #ifdef FEAT_CSCOPE
1998 if (use_cscope) 1998 if (use_cscope)
1999 eof = cs_fgets(lbuf, LSIZE); 1999 eof = cs_fgets(lbuf, lbuf_size);
2000 else 2000 else
2001 #endif 2001 #endif
2002 eof = vim_fgets(lbuf, LSIZE, fp); 2002 eof = vim_fgets(lbuf, lbuf_size, fp);
2003 } while (!eof && vim_isblankline(lbuf)); 2003 } while (!eof && vim_isblankline(lbuf));
2004 2004
2005 if (eof) 2005 if (eof)
2006 { 2006 {
2007 #ifdef FEAT_EMACS_TAGS 2007 #ifdef FEAT_EMACS_TAGS
2228 2228
2229 parse_line: 2229 parse_line:
2230 // When the line is too long the NUL will not be in the 2230 // When the line is too long the NUL will not be in the
2231 // last-but-one byte (see vim_fgets()). 2231 // last-but-one byte (see vim_fgets()).
2232 // Has been reported for Mozilla JS with extremely long names. 2232 // Has been reported for Mozilla JS with extremely long names.
2233 // In that case we can't parse it and we ignore the line. 2233 // In that case we need to increase lbuf_size.
2234 if (lbuf[LSIZE - 2] != NUL 2234 if (lbuf[lbuf_size - 2] != NUL
2235 #ifdef FEAT_CSCOPE 2235 #ifdef FEAT_CSCOPE
2236 && !use_cscope 2236 && !use_cscope
2237 #endif 2237 #endif
2238 ) 2238 )
2239 { 2239 {
2240 if (p_verbose >= 5) 2240 lbuf_size *= 2;
2241 { 2241 vim_free(lbuf);
2242 verbose_enter(); 2242 lbuf = alloc(lbuf_size);
2243 msg(_("Ignoring long line in tags file")); 2243 if (lbuf == NULL)
2244 verbose_leave(); 2244 goto findtag_end;
2245 } 2245 // this will try the same thing again, make sure the offset is
2246 #ifdef FEAT_TAG_BINS 2246 // different
2247 if (state != TS_LINEAR) 2247 search_info.curr_offset = 0;
2248 {
2249 // Avoid getting stuck.
2250 linear = TRUE;
2251 state = TS_LINEAR;
2252 vim_fseek(fp, search_info.low_offset, SEEK_SET);
2253 }
2254 #endif
2255 continue; 2248 continue;
2256 } 2249 }
2257 2250
2258 /* 2251 /*
2259 * Figure out where the different strings are in this line. 2252 * Figure out where the different strings are in this line.
3365 #ifdef FEAT_EMACS_TAGS 3358 #ifdef FEAT_EMACS_TAGS
3366 if (tagp.is_etag && *str == ',')/* stop at ',' after line number */ 3359 if (tagp.is_etag && *str == ',')/* stop at ',' after line number */
3367 break; 3360 break;
3368 #endif 3361 #endif
3369 *pbuf_end++ = *str++; 3362 *pbuf_end++ = *str++;
3363 if (pbuf_end - pbuf + 1 >= LSIZE)
3364 break;
3370 } 3365 }
3371 *pbuf_end = NUL; 3366 *pbuf_end = NUL;
3372 3367
3373 #ifdef FEAT_EMACS_TAGS 3368 #ifdef FEAT_EMACS_TAGS
3374 if (!tagp.is_etag) 3369 if (!tagp.is_etag)