comparison src/tag.c @ 3131:52526aec4afb v7.3.336

updated for version 7.3.336 Problem: When a tags file specifies an encoding different from 'enc' it may hang and using a pattern doesn't work. Solution: Convert the whole line. Continue reading the header after the SORT tag. Add test83. (Yukihiro Nakadaira)
author Bram Moolenaar <bram@vim.org>
date Wed, 12 Oct 2011 19:53:52 +0200
parents 25672ad7f377
children 436b42f3cba1
comparison
equal deleted inserted replaced
3130:91b43bbb3701 3131:52526aec4afb
1275 other: minimal number of matches */ 1275 other: minimal number of matches */
1276 char_u *buf_ffname; /* name of buffer for priority */ 1276 char_u *buf_ffname; /* name of buffer for priority */
1277 { 1277 {
1278 FILE *fp; 1278 FILE *fp;
1279 char_u *lbuf; /* line buffer */ 1279 char_u *lbuf; /* line buffer */
1280 int lbuf_size = LSIZE; /* length of lbuf */
1280 char_u *tag_fname; /* name of tag file */ 1281 char_u *tag_fname; /* name of tag file */
1281 tagname_T tn; /* info for get_tagfname() */ 1282 tagname_T tn; /* info for get_tagfname() */
1282 int first_file; /* trying first tag file */ 1283 int first_file; /* trying first tag file */
1283 tagptrs_T tagp; 1284 tagptrs_T tagp;
1284 int did_open = FALSE; /* did open a tag file */ 1285 int did_open = FALSE; /* did open a tag file */
1289 int eof = FALSE; /* found end-of-file */ 1290 int eof = FALSE; /* found end-of-file */
1290 char_u *p; 1291 char_u *p;
1291 char_u *s; 1292 char_u *s;
1292 int i; 1293 int i;
1293 #ifdef FEAT_TAG_BINS 1294 #ifdef FEAT_TAG_BINS
1295 int tag_file_sorted = NUL; /* !_TAG_FILE_SORTED value */
1294 struct tag_search_info /* Binary search file offsets */ 1296 struct tag_search_info /* Binary search file offsets */
1295 { 1297 {
1296 off_t low_offset; /* offset for first char of first line that 1298 off_t low_offset; /* offset for first char of first line that
1297 could match */ 1299 could match */
1298 off_t high_offset; /* offset of char after last line that could 1300 off_t high_offset; /* offset of char after last line that could
1358 char_u *help_lang_find = NULL; /* lang to be found */ 1360 char_u *help_lang_find = NULL; /* lang to be found */
1359 char_u help_lang[3]; /* lang of current tags file */ 1361 char_u help_lang[3]; /* lang of current tags file */
1360 char_u *saved_pat = NULL; /* copy of pat[] */ 1362 char_u *saved_pat = NULL; /* copy of pat[] */
1361 #endif 1363 #endif
1362 1364
1363 /* Use two sets of variables for the pattern: "orgpat" holds the values
1364 * for the original pattern and "convpat" converted from 'encoding' to
1365 * encoding of the tags file. "pats" point to either one of these. */
1366 pat_T *pats;
1367 pat_T orgpat; /* holds unconverted pattern info */ 1365 pat_T orgpat; /* holds unconverted pattern info */
1368 #ifdef FEAT_MBYTE 1366 #ifdef FEAT_MBYTE
1369 pat_T convpat; /* holds converted pattern info */
1370 vimconv_T vimconv; 1367 vimconv_T vimconv;
1371 #endif 1368 #endif
1372 1369
1373 #ifdef FEAT_TAG_BINS 1370 #ifdef FEAT_TAG_BINS
1374 int findall = (mincount == MAXCOL || mincount == TAG_MANY); 1371 int findall = (mincount == MAXCOL || mincount == TAG_MANY);
1388 #endif 1385 #endif
1389 int verbose = (flags & TAG_VERBOSE); 1386 int verbose = (flags & TAG_VERBOSE);
1390 1387
1391 help_save = curbuf->b_help; 1388 help_save = curbuf->b_help;
1392 orgpat.pat = pat; 1389 orgpat.pat = pat;
1393 pats = &orgpat;
1394 #ifdef FEAT_MBYTE 1390 #ifdef FEAT_MBYTE
1395 vimconv.vc_type = CONV_NONE; 1391 vimconv.vc_type = CONV_NONE;
1396 #endif 1392 #endif
1397 1393
1398 /* 1394 /*
1399 * Allocate memory for the buffers that are used 1395 * Allocate memory for the buffers that are used
1400 */ 1396 */
1401 lbuf = alloc(LSIZE); 1397 lbuf = alloc(lbuf_size);
1402 tag_fname = alloc(MAXPATHL + 1); 1398 tag_fname = alloc(MAXPATHL + 1);
1403 #ifdef FEAT_EMACS_TAGS 1399 #ifdef FEAT_EMACS_TAGS
1404 ebuf = alloc(LSIZE); 1400 ebuf = alloc(LSIZE);
1405 #endif 1401 #endif
1406 for (mtt = 0; mtt < MT_COUNT; ++mtt) 1402 for (mtt = 0; mtt < MT_COUNT; ++mtt)
1422 * Initialize a few variables 1418 * Initialize a few variables
1423 */ 1419 */
1424 if (help_only) /* want tags from help file */ 1420 if (help_only) /* want tags from help file */
1425 curbuf->b_help = TRUE; /* will be restored later */ 1421 curbuf->b_help = TRUE; /* will be restored later */
1426 1422
1427 pats->len = (int)STRLEN(pat); 1423 orgpat.len = (int)STRLEN(pat);
1428 #ifdef FEAT_MULTI_LANG 1424 #ifdef FEAT_MULTI_LANG
1429 if (curbuf->b_help) 1425 if (curbuf->b_help)
1430 { 1426 {
1431 /* When "@ab" is specified use only the "ab" language, otherwise 1427 /* When "@ab" is specified use only the "ab" language, otherwise
1432 * search all languages. */ 1428 * search all languages. */
1433 if (pats->len > 3 && pat[pats->len - 3] == '@' 1429 if (orgpat.len > 3 && pat[orgpat.len - 3] == '@'
1434 && ASCII_ISALPHA(pat[pats->len - 2]) 1430 && ASCII_ISALPHA(pat[orgpat.len - 2])
1435 && ASCII_ISALPHA(pat[pats->len - 1])) 1431 && ASCII_ISALPHA(pat[orgpat.len - 1]))
1436 { 1432 {
1437 saved_pat = vim_strnsave(pat, pats->len - 3); 1433 saved_pat = vim_strnsave(pat, orgpat.len - 3);
1438 if (saved_pat != NULL) 1434 if (saved_pat != NULL)
1439 { 1435 {
1440 help_lang_find = &pat[pats->len - 2]; 1436 help_lang_find = &pat[orgpat.len - 2];
1441 pats->pat = saved_pat; 1437 orgpat.pat = saved_pat;
1442 pats->len -= 3; 1438 orgpat.len -= 3;
1443 } 1439 }
1444 } 1440 }
1445 } 1441 }
1446 #endif 1442 #endif
1447 if (p_tl != 0 && pats->len > p_tl) /* adjust for 'taglength' */ 1443 if (p_tl != 0 && orgpat.len > p_tl) /* adjust for 'taglength' */
1448 pats->len = p_tl; 1444 orgpat.len = p_tl;
1449 1445
1450 prepare_pats(pats, has_re); 1446 prepare_pats(&orgpat, has_re);
1451 1447
1452 #ifdef FEAT_TAG_BINS 1448 #ifdef FEAT_TAG_BINS
1453 /* This is only to avoid a compiler warning for using search_info 1449 /* This is only to avoid a compiler warning for using search_info
1454 * uninitialised. */ 1450 * uninitialised. */
1455 vim_memset(&search_info, 0, (size_t)1); 1451 vim_memset(&search_info, 0, (size_t)1);
1464 * tags files twice. 1460 * tags files twice.
1465 * When the tag file is case-fold sorted, it is either one or the other. 1461 * When the tag file is case-fold sorted, it is either one or the other.
1466 * Only ignore case when TAG_NOIC not used or 'ignorecase' set. 1462 * Only ignore case when TAG_NOIC not used or 'ignorecase' set.
1467 */ 1463 */
1468 #ifdef FEAT_TAG_BINS 1464 #ifdef FEAT_TAG_BINS
1469 pats->regmatch.rm_ic = ((p_ic || !noic) 1465 orgpat.regmatch.rm_ic = ((p_ic || !noic)
1470 && (findall || pats->headlen == 0 || !p_tbs)); 1466 && (findall || orgpat.headlen == 0 || !p_tbs));
1471 for (round = 1; round <= 2; ++round) 1467 for (round = 1; round <= 2; ++round)
1472 { 1468 {
1473 linear = (pats->headlen == 0 || !p_tbs || round == 2); 1469 linear = (orgpat.headlen == 0 || !p_tbs || round == 2);
1474 #else 1470 #else
1475 pats->regmatch.rm_ic = (p_ic || !noic); 1471 orgpat.regmatch.rm_ic = (p_ic || !noic);
1476 #endif 1472 #endif
1477 1473
1478 /* 1474 /*
1479 * Try tag file names from tags option one by one. 1475 * Try tag file names from tags option one by one.
1480 */ 1476 */
1698 #endif 1694 #endif
1699 break; /* end of file */ 1695 break; /* end of file */
1700 } 1696 }
1701 } 1697 }
1702 line_read_in: 1698 line_read_in:
1699
1700 #ifdef FEAT_MBYTE
1701 if (vimconv.vc_type != CONV_NONE)
1702 {
1703 char_u *conv_line;
1704 int len;
1705
1706 /* Convert every line. Converting the pattern from 'enc' to
1707 * the tags file encoding doesn't work, because characters are
1708 * not recognized. */
1709 conv_line = string_convert(&vimconv, lbuf, NULL);
1710 if (conv_line != NULL)
1711 {
1712 /* Copy or swap lbuf and conv_line. */
1713 len = (int)STRLEN(conv_line) + 1;
1714 if (len > lbuf_size)
1715 {
1716 vim_free(lbuf);
1717 lbuf = conv_line;
1718 lbuf_size = len;
1719 }
1720 else
1721 {
1722 STRCPY(lbuf, conv_line);
1723 vim_free(conv_line);
1724 }
1725 }
1726 }
1727 #endif
1728
1703 1729
1704 #ifdef FEAT_EMACS_TAGS 1730 #ifdef FEAT_EMACS_TAGS
1705 /* 1731 /*
1706 * Emacs tags line with CTRL-L: New file name on next line. 1732 * Emacs tags line with CTRL-L: New file name on next line.
1707 * The file name is followed by a ','. 1733 * The file name is followed by a ','.
1768 * When still at the start of the file, check for Emacs tags file 1794 * When still at the start of the file, check for Emacs tags file
1769 * format, and for "not sorted" flag. 1795 * format, and for "not sorted" flag.
1770 */ 1796 */
1771 if (state == TS_START) 1797 if (state == TS_START)
1772 { 1798 {
1799 if (STRNCMP(lbuf, "!_TAG_", 6) <= 0)
1800 {
1801 /*
1802 * Read header line.
1803 */
1804 #ifdef FEAT_TAG_BINS
1805 if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0)
1806 tag_file_sorted = lbuf[18];
1807 #endif
1808 #ifdef FEAT_MBYTE
1809 if (STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
1810 {
1811 /* Prepare to convert every line from the specified
1812 * encoding to 'encoding'. */
1813 for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
1814 ;
1815 *p = NUL;
1816 convert_setup(&vimconv, lbuf + 20, p_enc);
1817 }
1818 #endif
1819
1820 /* Read the next line. Unrecognized flags are ignored. */
1821 continue;
1822 }
1823
1824 /* Headers ends. */
1825
1773 #ifdef FEAT_TAG_BINS 1826 #ifdef FEAT_TAG_BINS
1774 /* 1827 /*
1775 * When there is no tag head, or ignoring case, need to do a 1828 * When there is no tag head, or ignoring case, need to do a
1776 * linear search. 1829 * linear search.
1777 * When no "!_TAG_" is found, default to binary search. If 1830 * When no "!_TAG_" is found, default to binary search. If
1784 if (linear || use_cscope) 1837 if (linear || use_cscope)
1785 # else 1838 # else
1786 if (linear) 1839 if (linear)
1787 # endif 1840 # endif
1788 state = TS_LINEAR; 1841 state = TS_LINEAR;
1789 else if (STRNCMP(lbuf, "!_TAG_", 6) > 0) 1842 else if (tag_file_sorted == NUL)
1790 state = TS_BINARY; 1843 state = TS_BINARY;
1791 else if (STRNCMP(lbuf, "!_TAG_FILE_SORTED\t", 18) == 0) 1844 else if (tag_file_sorted == '1')
1792 {
1793 /* Check sorted flag */
1794 if (lbuf[18] == '1')
1795 state = TS_BINARY; 1845 state = TS_BINARY;
1796 else if (lbuf[18] == '2') 1846 else if (tag_file_sorted == '2')
1797 { 1847 {
1798 state = TS_BINARY; 1848 state = TS_BINARY;
1799 sortic = TRUE; 1849 sortic = TRUE;
1800 pats->regmatch.rm_ic = (p_ic || !noic); 1850 orgpat.regmatch.rm_ic = (p_ic || !noic);
1801 } 1851 }
1802 else 1852 else
1803 state = TS_LINEAR; 1853 state = TS_LINEAR;
1804 } 1854
1805 1855 if (state == TS_BINARY && orgpat.regmatch.rm_ic && !sortic)
1806 if (state == TS_BINARY && pats->regmatch.rm_ic && !sortic)
1807 { 1856 {
1808 /* binary search won't work for ignoring case, use linear 1857 /* binary search won't work for ignoring case, use linear
1809 * search. */ 1858 * search. */
1810 linear = TRUE; 1859 linear = TRUE;
1811 state = TS_LINEAR; 1860 state = TS_LINEAR;
1841 continue; 1890 continue;
1842 } 1891 }
1843 #endif 1892 #endif
1844 } 1893 }
1845 1894
1846 #ifdef FEAT_MBYTE
1847 if (lbuf[0] == '!' && pats == &orgpat
1848 && STRNCMP(lbuf, "!_TAG_FILE_ENCODING\t", 20) == 0)
1849 {
1850 /* Convert the search pattern from 'encoding' to the
1851 * specified encoding. */
1852 for (p = lbuf + 20; *p > ' ' && *p < 127; ++p)
1853 ;
1854 *p = NUL;
1855 convert_setup(&vimconv, p_enc, lbuf + 20);
1856 if (vimconv.vc_type != CONV_NONE)
1857 {
1858 convpat.pat = string_convert(&vimconv, pats->pat, NULL);
1859 if (convpat.pat != NULL)
1860 {
1861 pats = &convpat;
1862 pats->len = (int)STRLEN(pats->pat);
1863 prepare_pats(pats, has_re);
1864 pats->regmatch.rm_ic = orgpat.regmatch.rm_ic;
1865 }
1866 }
1867
1868 /* Prepare for converting a match the other way around. */
1869 convert_setup(&vimconv, lbuf + 20, p_enc);
1870 continue;
1871 }
1872 #endif
1873
1874 /* 1895 /*
1875 * Figure out where the different strings are in this line. 1896 * Figure out where the different strings are in this line.
1876 * For "normal" tags: Do a quick check if the tag matches. 1897 * For "normal" tags: Do a quick check if the tag matches.
1877 * This speeds up tag searching a lot! 1898 * This speeds up tag searching a lot!
1878 */ 1899 */
1879 if (pats->headlen 1900 if (orgpat.headlen
1880 #ifdef FEAT_EMACS_TAGS 1901 #ifdef FEAT_EMACS_TAGS
1881 && !is_etag 1902 && !is_etag
1882 #endif 1903 #endif
1883 ) 1904 )
1884 { 1905 {
1931 * there is no regexp, or the tag is too short. 1952 * there is no regexp, or the tag is too short.
1932 */ 1953 */
1933 cmplen = (int)(tagp.tagname_end - tagp.tagname); 1954 cmplen = (int)(tagp.tagname_end - tagp.tagname);
1934 if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ 1955 if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
1935 cmplen = p_tl; 1956 cmplen = p_tl;
1936 if (has_re && pats->headlen < cmplen) 1957 if (has_re && orgpat.headlen < cmplen)
1937 cmplen = pats->headlen; 1958 cmplen = orgpat.headlen;
1938 else if (state == TS_LINEAR && pats->headlen != cmplen) 1959 else if (state == TS_LINEAR && orgpat.headlen != cmplen)
1939 continue; 1960 continue;
1940 1961
1941 #ifdef FEAT_TAG_BINS 1962 #ifdef FEAT_TAG_BINS
1942 if (state == TS_BINARY) 1963 if (state == TS_BINARY)
1943 { 1964 {
1952 1973
1953 /* 1974 /*
1954 * Compare the current tag with the searched tag. 1975 * Compare the current tag with the searched tag.
1955 */ 1976 */
1956 if (sortic) 1977 if (sortic)
1957 tagcmp = tag_strnicmp(tagp.tagname, pats->head, 1978 tagcmp = tag_strnicmp(tagp.tagname, orgpat.head,
1958 (size_t)cmplen); 1979 (size_t)cmplen);
1959 else 1980 else
1960 tagcmp = STRNCMP(tagp.tagname, pats->head, cmplen); 1981 tagcmp = STRNCMP(tagp.tagname, orgpat.head, cmplen);
1961 1982
1962 /* 1983 /*
1963 * A match with a shorter tag means to search forward. 1984 * A match with a shorter tag means to search forward.
1964 * A match with a longer tag means to search backward. 1985 * A match with a longer tag means to search backward.
1965 */ 1986 */
1966 if (tagcmp == 0) 1987 if (tagcmp == 0)
1967 { 1988 {
1968 if (cmplen < pats->headlen) 1989 if (cmplen < orgpat.headlen)
1969 tagcmp = -1; 1990 tagcmp = -1;
1970 else if (cmplen > pats->headlen) 1991 else if (cmplen > orgpat.headlen)
1971 tagcmp = 1; 1992 tagcmp = 1;
1972 } 1993 }
1973 1994
1974 if (tagcmp == 0) 1995 if (tagcmp == 0)
1975 { 1996 {
2009 /* No match yet and are at the end of the binary search. */ 2030 /* No match yet and are at the end of the binary search. */
2010 break; 2031 break;
2011 } 2032 }
2012 else if (state == TS_SKIP_BACK) 2033 else if (state == TS_SKIP_BACK)
2013 { 2034 {
2014 if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0) 2035 if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2015 state = TS_STEP_FORWARD; 2036 state = TS_STEP_FORWARD;
2016 else 2037 else
2017 /* Have to skip back more. Restore the curr_offset 2038 /* Have to skip back more. Restore the curr_offset
2018 * used, otherwise we get stuck at a long line. */ 2039 * used, otherwise we get stuck at a long line. */
2019 search_info.curr_offset = search_info.curr_offset_used; 2040 search_info.curr_offset = search_info.curr_offset_used;
2020 continue; 2041 continue;
2021 } 2042 }
2022 else if (state == TS_STEP_FORWARD) 2043 else if (state == TS_STEP_FORWARD)
2023 { 2044 {
2024 if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0) 2045 if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2025 { 2046 {
2026 if ((off_t)ftell(fp) > search_info.match_offset) 2047 if ((off_t)ftell(fp) > search_info.match_offset)
2027 break; /* past last match */ 2048 break; /* past last match */
2028 else 2049 else
2029 continue; /* before first match */ 2050 continue; /* before first match */
2030 } 2051 }
2031 } 2052 }
2032 else 2053 else
2033 #endif 2054 #endif
2034 /* skip this match if it can't match */ 2055 /* skip this match if it can't match */
2035 if (MB_STRNICMP(tagp.tagname, pats->head, cmplen) != 0) 2056 if (MB_STRNICMP(tagp.tagname, orgpat.head, cmplen) != 0)
2036 continue; 2057 continue;
2037 2058
2038 /* 2059 /*
2039 * Can be a matching tag, isolate the file name and command. 2060 * Can be a matching tag, isolate the file name and command.
2040 */ 2061 */
2081 */ 2102 */
2082 cmplen = (int)(tagp.tagname_end - tagp.tagname); 2103 cmplen = (int)(tagp.tagname_end - tagp.tagname);
2083 if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */ 2104 if (p_tl != 0 && cmplen > p_tl) /* adjust for 'taglength' */
2084 cmplen = p_tl; 2105 cmplen = p_tl;
2085 /* if tag length does not match, don't try comparing */ 2106 /* if tag length does not match, don't try comparing */
2086 if (pats->len != cmplen) 2107 if (orgpat.len != cmplen)
2087 match = FALSE; 2108 match = FALSE;
2088 else 2109 else
2089 { 2110 {
2090 if (pats->regmatch.rm_ic) 2111 if (orgpat.regmatch.rm_ic)
2091 { 2112 {
2092 match = (MB_STRNICMP(tagp.tagname, pats->pat, cmplen) == 0); 2113 match = (MB_STRNICMP(tagp.tagname, orgpat.pat, cmplen) == 0);
2093 if (match) 2114 if (match)
2094 match_no_ic = (STRNCMP(tagp.tagname, pats->pat, 2115 match_no_ic = (STRNCMP(tagp.tagname, orgpat.pat,
2095 cmplen) == 0); 2116 cmplen) == 0);
2096 } 2117 }
2097 else 2118 else
2098 match = (STRNCMP(tagp.tagname, pats->pat, cmplen) == 0); 2119 match = (STRNCMP(tagp.tagname, orgpat.pat, cmplen) == 0);
2099 } 2120 }
2100 2121
2101 /* 2122 /*
2102 * Has a regexp: Also find tags matching regexp. 2123 * Has a regexp: Also find tags matching regexp.
2103 */ 2124 */
2104 match_re = FALSE; 2125 match_re = FALSE;
2105 if (!match && pats->regmatch.regprog != NULL) 2126 if (!match && orgpat.regmatch.regprog != NULL)
2106 { 2127 {
2107 int cc; 2128 int cc;
2108 2129
2109 cc = *tagp.tagname_end; 2130 cc = *tagp.tagname_end;
2110 *tagp.tagname_end = NUL; 2131 *tagp.tagname_end = NUL;
2111 match = vim_regexec(&pats->regmatch, tagp.tagname, (colnr_T)0); 2132 match = vim_regexec(&orgpat.regmatch, tagp.tagname, (colnr_T)0);
2112 if (match) 2133 if (match)
2113 { 2134 {
2114 matchoff = (int)(pats->regmatch.startp[0] - tagp.tagname); 2135 matchoff = (int)(orgpat.regmatch.startp[0] - tagp.tagname);
2115 if (pats->regmatch.rm_ic) 2136 if (orgpat.regmatch.rm_ic)
2116 { 2137 {
2117 pats->regmatch.rm_ic = FALSE; 2138 orgpat.regmatch.rm_ic = FALSE;
2118 match_no_ic = vim_regexec(&pats->regmatch, tagp.tagname, 2139 match_no_ic = vim_regexec(&orgpat.regmatch, tagp.tagname,
2119 (colnr_T)0); 2140 (colnr_T)0);
2120 pats->regmatch.rm_ic = TRUE; 2141 orgpat.regmatch.rm_ic = TRUE;
2121 } 2142 }
2122 } 2143 }
2123 *tagp.tagname_end = cc; 2144 *tagp.tagname_end = cc;
2124 match_re = TRUE; 2145 match_re = TRUE;
2125 } 2146 }
2172 if (is_current) 2193 if (is_current)
2173 mtt = MT_GL_CUR; 2194 mtt = MT_GL_CUR;
2174 else 2195 else
2175 mtt = MT_GL_OTH; 2196 mtt = MT_GL_OTH;
2176 } 2197 }
2177 if (pats->regmatch.rm_ic && !match_no_ic) 2198 if (orgpat.regmatch.rm_ic && !match_no_ic)
2178 mtt += MT_IC_OFF; 2199 mtt += MT_IC_OFF;
2179 if (match_re) 2200 if (match_re)
2180 mtt += MT_RE_OFF; 2201 mtt += MT_RE_OFF;
2181 } 2202 }
2182 2203
2185 * Store the info we need later, which depends on the kind of 2206 * Store the info we need later, which depends on the kind of
2186 * tags we are dealing with. 2207 * tags we are dealing with.
2187 */ 2208 */
2188 if (ga_grow(&ga_match[mtt], 1) == OK) 2209 if (ga_grow(&ga_match[mtt], 1) == OK)
2189 { 2210 {
2190 #ifdef FEAT_MBYTE
2191 char_u *conv_line = NULL;
2192 char_u *lbuf_line = lbuf;
2193
2194 if (vimconv.vc_type != CONV_NONE)
2195 {
2196 /* Convert the tag line from the encoding of the tags
2197 * file to 'encoding'. Then parse the line again. */
2198 conv_line = string_convert(&vimconv, lbuf, NULL);
2199 if (conv_line != NULL)
2200 {
2201 if (parse_tag_line(conv_line,
2202 #ifdef FEAT_EMACS_TAGS
2203 is_etag,
2204 #endif
2205 &tagp) == OK)
2206 lbuf_line = conv_line;
2207 else
2208 /* doesn't work, go back to unconverted line. */
2209 (void)parse_tag_line(lbuf,
2210 #ifdef FEAT_EMACS_TAGS
2211 is_etag,
2212 #endif
2213 &tagp);
2214 }
2215 }
2216 #else
2217 # define lbuf_line lbuf
2218 #endif
2219 if (help_only) 2211 if (help_only)
2220 { 2212 {
2221 #ifdef FEAT_MULTI_LANG 2213 #ifdef FEAT_MULTI_LANG
2222 # define ML_EXTRA 3 2214 # define ML_EXTRA 3
2223 #else 2215 #else
2305 * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf> 2297 * Emacs tag: <mtt><tag_fname><NUL><ebuf><NUL><lbuf>
2306 * other tag: <mtt><tag_fname><NUL><NUL><lbuf> 2298 * other tag: <mtt><tag_fname><NUL><NUL><lbuf>
2307 * without Emacs tags: <mtt><tag_fname><NUL><lbuf> 2299 * without Emacs tags: <mtt><tag_fname><NUL><lbuf>
2308 */ 2300 */
2309 len = (int)STRLEN(tag_fname) 2301 len = (int)STRLEN(tag_fname)
2310 + (int)STRLEN(lbuf_line) + 3; 2302 + (int)STRLEN(lbuf) + 3;
2311 #ifdef FEAT_EMACS_TAGS 2303 #ifdef FEAT_EMACS_TAGS
2312 if (is_etag) 2304 if (is_etag)
2313 len += (int)STRLEN(ebuf) + 1; 2305 len += (int)STRLEN(ebuf) + 1;
2314 else 2306 else
2315 ++len; 2307 ++len;
2335 s += STRLEN(ebuf) + 1; 2327 s += STRLEN(ebuf) + 1;
2336 } 2328 }
2337 else 2329 else
2338 *s++ = NUL; 2330 *s++ = NUL;
2339 #endif 2331 #endif
2340 STRCPY(s, lbuf_line); 2332 STRCPY(s, lbuf);
2341 } 2333 }
2342 } 2334 }
2343 2335
2344 if (mfp != NULL) 2336 if (mfp != NULL)
2345 { 2337 {
2371 ++match_count; 2363 ++match_count;
2372 } 2364 }
2373 else 2365 else
2374 vim_free(mfp); 2366 vim_free(mfp);
2375 } 2367 }
2376 #ifdef FEAT_MBYTE
2377 /* Note: this makes the values in "tagp" invalid! */
2378 vim_free(conv_line);
2379 #endif
2380 } 2368 }
2381 else /* Out of memory! Just forget about the rest. */ 2369 else /* Out of memory! Just forget about the rest. */
2382 { 2370 {
2383 retval = OK; 2371 retval = OK;
2384 stop_searching = TRUE; 2372 stop_searching = TRUE;
2413 fclose(incstack[incstack_idx].fp); 2401 fclose(incstack[incstack_idx].fp);
2414 vim_free(incstack[incstack_idx].etag_fname); 2402 vim_free(incstack[incstack_idx].etag_fname);
2415 } 2403 }
2416 #endif 2404 #endif
2417 #ifdef FEAT_MBYTE 2405 #ifdef FEAT_MBYTE
2418 if (pats == &convpat)
2419 {
2420 /* Go back from converted pattern to original pattern. */
2421 vim_free(pats->pat);
2422 vim_free(pats->regmatch.regprog);
2423 orgpat.regmatch.rm_ic = pats->regmatch.rm_ic;
2424 pats = &orgpat;
2425 }
2426 if (vimconv.vc_type != CONV_NONE) 2406 if (vimconv.vc_type != CONV_NONE)
2427 convert_setup(&vimconv, NULL, NULL); 2407 convert_setup(&vimconv, NULL, NULL);
2428 #endif 2408 #endif
2429 2409
2430 #ifdef FEAT_TAG_BINS 2410 #ifdef FEAT_TAG_BINS
2411 tag_file_sorted = NUL;
2431 if (sort_error) 2412 if (sort_error)
2432 { 2413 {
2433 EMSG2(_("E432: Tags file not sorted: %s"), tag_fname); 2414 EMSG2(_("E432: Tags file not sorted: %s"), tag_fname);
2434 sort_error = FALSE; 2415 sort_error = FALSE;
2435 } 2416 }
2459 tagname_free(&tn); 2440 tagname_free(&tn);
2460 2441
2461 #ifdef FEAT_TAG_BINS 2442 #ifdef FEAT_TAG_BINS
2462 /* stop searching when already did a linear search, or when TAG_NOIC 2443 /* stop searching when already did a linear search, or when TAG_NOIC
2463 * used, and 'ignorecase' not set or already did case-ignore search */ 2444 * used, and 'ignorecase' not set or already did case-ignore search */
2464 if (stop_searching || linear || (!p_ic && noic) || pats->regmatch.rm_ic) 2445 if (stop_searching || linear || (!p_ic && noic) || orgpat.regmatch.rm_ic)
2465 break; 2446 break;
2466 # ifdef FEAT_CSCOPE 2447 # ifdef FEAT_CSCOPE
2467 if (use_cscope) 2448 if (use_cscope)
2468 break; 2449 break;
2469 # endif 2450 # endif
2470 pats->regmatch.rm_ic = TRUE; /* try another time while ignoring case */ 2451 orgpat.regmatch.rm_ic = TRUE; /* try another time while ignoring case */
2471 } 2452 }
2472 #endif 2453 #endif
2473 2454
2474 if (!stop_searching) 2455 if (!stop_searching)
2475 { 2456 {
2478 retval = OK; /* It's OK even when no tag found */ 2459 retval = OK; /* It's OK even when no tag found */
2479 } 2460 }
2480 2461
2481 findtag_end: 2462 findtag_end:
2482 vim_free(lbuf); 2463 vim_free(lbuf);
2483 vim_free(pats->regmatch.regprog); 2464 vim_free(orgpat.regmatch.regprog);
2484 vim_free(tag_fname); 2465 vim_free(tag_fname);
2485 #ifdef FEAT_EMACS_TAGS 2466 #ifdef FEAT_EMACS_TAGS
2486 vim_free(ebuf); 2467 vim_free(ebuf);
2487 #endif 2468 #endif
2488 2469