Mercurial > vim
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) |