comparison src/tag.c @ 9387:f094d4085014 v7.4.1975

commit https://github.com/vim/vim/commit/8767f52fbfd4f053ce00a978227c95f1d7d323fe Author: Bram Moolenaar <Bram@vim.org> Date: Fri Jul 1 17:17:39 2016 +0200 patch 7.4.1975 Problem: On MS-Windows large files (> 2Gbyte) cause problems. Solution: Use "off_T" instead of "off_t". Use "stat_T" instead of "struct stat". Use 64 bit system functions if available. (Ken Takata)
author Christian Brabandt <cb@256bit.org>
date Fri, 01 Jul 2016 17:30:07 +0200
parents 0a3bc9fdea20
children 67781bb0a61a
comparison
equal deleted inserted replaced
9386:80deab13679b 9387:f094d4085014
80 80
81 static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack"); 81 static char_u *bottommsg = (char_u *)N_("E555: at bottom of tag stack");
82 static char_u *topmsg = (char_u *)N_("E556: at top of tag stack"); 82 static char_u *topmsg = (char_u *)N_("E556: at top of tag stack");
83 83
84 static char_u *tagmatchname = NULL; /* name of last used tag */ 84 static char_u *tagmatchname = NULL; /* name of last used tag */
85
86 /*
87 * We use ftello() here, if available. It returns off_t instead of long,
88 * which helps if long is 32 bit and off_t is 64 bit.
89 * We assume that when fseeko() is available then ftello() is too.
90 */
91 #ifdef HAVE_FSEEKO
92 # define ftell ftello
93 #endif
94 85
95 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) 86 #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
96 /* 87 /*
97 * Tag for preview window is remembered separately, to avoid messing up the 88 * Tag for preview window is remembered separately, to avoid messing up the
98 * normal tagstack. 89 * normal tagstack.
1295 int i; 1286 int i;
1296 #ifdef FEAT_TAG_BINS 1287 #ifdef FEAT_TAG_BINS
1297 int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */ 1288 int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */
1298 struct tag_search_info /* Binary search file offsets */ 1289 struct tag_search_info /* Binary search file offsets */
1299 { 1290 {
1300 off_t low_offset; /* offset for first char of first line that 1291 off_T low_offset; /* offset for first char of first line that
1301 could match */ 1292 could match */
1302 off_t high_offset; /* offset of char after last line that could 1293 off_T high_offset; /* offset of char after last line that could
1303 match */ 1294 match */
1304 off_t curr_offset; /* Current file offset in search range */ 1295 off_T curr_offset; /* Current file offset in search range */
1305 off_t curr_offset_used; /* curr_offset used when skipping back */ 1296 off_T curr_offset_used; /* curr_offset used when skipping back */
1306 off_t match_offset; /* Where the binary search found a tag */ 1297 off_T match_offset; /* Where the binary search found a tag */
1307 int low_char; /* first char at low_offset */ 1298 int low_char; /* first char at low_offset */
1308 int high_char; /* first char at high_offset */ 1299 int high_char; /* first char at high_offset */
1309 } search_info; 1300 } search_info;
1310 off_t filesize; 1301 off_T filesize;
1311 int tagcmp; 1302 int tagcmp;
1312 off_t offset; 1303 off_T offset;
1313 int round; 1304 int round;
1314 #endif 1305 #endif
1315 enum 1306 enum
1316 { 1307 {
1317 TS_START, /* at start of file */ 1308 TS_START, /* at start of file */
1638 */ 1629 */
1639 if (state == TS_BINARY || state == TS_SKIP_BACK) 1630 if (state == TS_BINARY || state == TS_SKIP_BACK)
1640 { 1631 {
1641 /* Adjust the search file offset to the correct position */ 1632 /* Adjust the search file offset to the correct position */
1642 search_info.curr_offset_used = search_info.curr_offset; 1633 search_info.curr_offset_used = search_info.curr_offset;
1643 #ifdef HAVE_FSEEKO 1634 vim_fseek(fp, search_info.curr_offset, SEEK_SET);
1644 fseeko(fp, search_info.curr_offset, SEEK_SET);
1645 #else
1646 fseek(fp, (long)search_info.curr_offset, SEEK_SET);
1647 #endif
1648 eof = tag_fgets(lbuf, LSIZE, fp); 1635 eof = tag_fgets(lbuf, LSIZE, fp);
1649 if (!eof && search_info.curr_offset != 0) 1636 if (!eof && search_info.curr_offset != 0)
1650 { 1637 {
1651 /* The explicit cast is to work around a bug in gcc 3.4.2 1638 /* The explicit cast is to work around a bug in gcc 3.4.2
1652 * (repeated below). */ 1639 * (repeated below). */
1653 search_info.curr_offset = ftell(fp); 1640 search_info.curr_offset = vim_ftell(fp);
1654 if (search_info.curr_offset == search_info.high_offset) 1641 if (search_info.curr_offset == search_info.high_offset)
1655 { 1642 {
1656 /* oops, gone a bit too far; try from low offset */ 1643 /* oops, gone a bit too far; try from low offset */
1657 #ifdef HAVE_FSEEKO 1644 vim_fseek(fp, search_info.low_offset, SEEK_SET);
1658 fseeko(fp, search_info.low_offset, SEEK_SET);
1659 #else
1660 fseek(fp, (long)search_info.low_offset, SEEK_SET);
1661 #endif
1662 search_info.curr_offset = search_info.low_offset; 1645 search_info.curr_offset = search_info.low_offset;
1663 } 1646 }
1664 eof = tag_fgets(lbuf, LSIZE, fp); 1647 eof = tag_fgets(lbuf, LSIZE, fp);
1665 } 1648 }
1666 /* skip empty and blank lines */ 1649 /* skip empty and blank lines */
1667 while (!eof && vim_isblankline(lbuf)) 1650 while (!eof && vim_isblankline(lbuf))
1668 { 1651 {
1669 search_info.curr_offset = ftell(fp); 1652 search_info.curr_offset = vim_ftell(fp);
1670 eof = tag_fgets(lbuf, LSIZE, fp); 1653 eof = tag_fgets(lbuf, LSIZE, fp);
1671 } 1654 }
1672 if (eof) 1655 if (eof)
1673 { 1656 {
1674 /* Hit end of file. Skip backwards. */ 1657 /* Hit end of file. Skip backwards. */
1675 state = TS_SKIP_BACK; 1658 state = TS_SKIP_BACK;
1676 search_info.match_offset = ftell(fp); 1659 search_info.match_offset = vim_ftell(fp);
1677 search_info.curr_offset = search_info.curr_offset_used; 1660 search_info.curr_offset = search_info.curr_offset_used;
1678 continue; 1661 continue;
1679 } 1662 }
1680 } 1663 }
1681 1664
1897 */ 1880 */
1898 if (state == TS_BINARY) 1881 if (state == TS_BINARY)
1899 { 1882 {
1900 /* Get the tag file size (don't use mch_fstat(), it's not 1883 /* Get the tag file size (don't use mch_fstat(), it's not
1901 * portable). */ 1884 * portable). */
1902 if ((filesize = lseek(fileno(fp), 1885 if ((filesize = vim_lseek(fileno(fp),
1903 (off_t)0L, SEEK_END)) <= 0) 1886 (off_T)0L, SEEK_END)) <= 0)
1904 state = TS_LINEAR; 1887 state = TS_LINEAR;
1905 else 1888 else
1906 { 1889 {
1907 lseek(fileno(fp), (off_t)0L, SEEK_SET); 1890 vim_lseek(fileno(fp), (off_T)0L, SEEK_SET);
1908 1891
1909 /* Calculate the first read offset in the file. Start 1892 /* Calculate the first read offset in the file. Start
1910 * the search in the middle of the file. */ 1893 * the search in the middle of the file. */
1911 search_info.low_offset = 0; 1894 search_info.low_offset = 0;
1912 search_info.low_char = 0; 1895 search_info.low_char = 0;
1954 if (state != TS_LINEAR) 1937 if (state != TS_LINEAR)
1955 { 1938 {
1956 /* Avoid getting stuck. */ 1939 /* Avoid getting stuck. */
1957 linear = TRUE; 1940 linear = TRUE;
1958 state = TS_LINEAR; 1941 state = TS_LINEAR;
1959 # ifdef HAVE_FSEEKO 1942 vim_fseek(fp, search_info.low_offset, SEEK_SET);
1960 fseeko(fp, search_info.low_offset, SEEK_SET);
1961 # else
1962 fseek(fp, (long)search_info.low_offset, SEEK_SET);
1963 # endif
1964 } 1943 }
1965 #endif 1944 #endif
1966 continue; 1945 continue;
1967 } 1946 }
1968 1947
2056 search_info.match_offset = search_info.curr_offset; 2035 search_info.match_offset = search_info.curr_offset;
2057 continue; 2036 continue;
2058 } 2037 }
2059 if (tagcmp < 0) 2038 if (tagcmp < 0)
2060 { 2039 {
2061 search_info.curr_offset = ftell(fp); 2040 search_info.curr_offset = vim_ftell(fp);
2062 if (search_info.curr_offset < search_info.high_offset) 2041 if (search_info.curr_offset < search_info.high_offset)
2063 { 2042 {
2064 search_info.low_offset = search_info.curr_offset; 2043 search_info.low_offset = search_info.curr_offset;
2065 if (sortic) 2044 if (sortic)
2066 search_info.low_char = 2045 search_info.low_char =
2097 } 2076 }
2098 else if (state == TS_STEP_FORWARD) 2077 else if (state == TS_STEP_FORWARD)
2099 { 2078 {
2100 if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0) 2079 if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2101 { 2080 {
2102 if ((off_t)ftell(fp) > search_info.match_offset) 2081 if ((off_T)vim_ftell(fp) > search_info.match_offset)
2103 break; /* past last match */ 2082 break; /* past last match */
2104 else 2083 else
2105 continue; /* before first match */ 2084 continue; /* before first match */
2106 } 2085 }
2107 } 2086 }
2442 { 2421 {
2443 EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname); 2422 EMSG2(_("E431: Format error in tags file \"%s\""), tag_fname);
2444 #ifdef FEAT_CSCOPE 2423 #ifdef FEAT_CSCOPE
2445 if (!use_cscope) 2424 if (!use_cscope)
2446 #endif 2425 #endif
2447 EMSGN(_("Before byte %ld"), (long)ftell(fp)); 2426 EMSGN(_("Before byte %ld"), (long)vim_ftell(fp));
2448 stop_searching = TRUE; 2427 stop_searching = TRUE;
2449 line_error = FALSE; 2428 line_error = FALSE;
2450 } 2429 }
2451 2430
2452 #ifdef FEAT_CSCOPE 2431 #ifdef FEAT_CSCOPE
3537 3516
3538 if (components > 0) /* strip one preceding component */ 3517 if (components > 0) /* strip one preceding component */
3539 { 3518 {
3540 int do_strip = FALSE; 3519 int do_strip = FALSE;
3541 char_u saved_char; 3520 char_u saved_char;
3542 struct stat st; 3521 stat_T st;
3543 3522
3544 /* Don't strip for an erroneous file name. */ 3523 /* Don't strip for an erroneous file name. */
3545 if (!stripping_disabled) 3524 if (!stripping_disabled)
3546 { 3525 {
3547 /* If the preceding component does not exist in the file 3526 /* If the preceding component does not exist in the file
3582 stripping_disabled = TRUE; 3561 stripping_disabled = TRUE;
3583 *tail = saved_char; 3562 *tail = saved_char;
3584 #ifdef UNIX 3563 #ifdef UNIX
3585 if (do_strip) 3564 if (do_strip)
3586 { 3565 {
3587 struct stat new_st; 3566 stat_T new_st;
3588 3567
3589 /* On Unix, the check for the unstripped file name 3568 /* On Unix, the check for the unstripped file name
3590 * above works also for a symbolic link pointing to 3569 * above works also for a symbolic link pointing to
3591 * a searchable directory. But then the parent of 3570 * a searchable directory. But then the parent of
3592 * the directory pointed to by the link must be the 3571 * the directory pointed to by the link must be the