Mercurial > vim
comparison src/tag.c @ 27942:4a76119d6372 v8.2.4496
patch 8.2.4496: Coverity gives warnings after tags code refactoring
Commit: https://github.com/vim/vim/commit/fe9112e630672dcd95e6b384c86f50c27ec10fed
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Mar 3 10:44:17 2022 +0000
patch 8.2.4496: Coverity gives warnings after tags code refactoring
Problem: Coverity gives warnings after tags code refactoring.
Solution: Avoid the warnings. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/9882)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 03 Mar 2022 11:45:04 +0100 |
parents | b65a50d2fa4f |
children | 495418c6cac8 |
comparison
equal
deleted
inserted
replaced
27941:3b23146c526d | 27942:4a76119d6372 |
---|---|
1578 | 1578 |
1579 /* | 1579 /* |
1580 * State information used during a tag search | 1580 * State information used during a tag search |
1581 */ | 1581 */ |
1582 typedef struct { | 1582 typedef struct { |
1583 char_u *tag_fname; // name of tag file | |
1583 pat_T orgpat; // holds unconverted pattern info | 1584 pat_T orgpat; // holds unconverted pattern info |
1584 #ifdef FEAT_MULTI_LANG | 1585 #ifdef FEAT_MULTI_LANG |
1585 char_u *help_lang_find; // lang to be found | 1586 char_u *help_lang_find; // lang to be found |
1586 int is_txt; // flag of file extension | 1587 int is_txt; // flag of file extension |
1587 #endif | 1588 #endif |
1608 static int | 1609 static int |
1609 findtags_state_init(findtags_state_T *st, char_u *pat, int mincount) | 1610 findtags_state_init(findtags_state_T *st, char_u *pat, int mincount) |
1610 { | 1611 { |
1611 int mtt; | 1612 int mtt; |
1612 | 1613 |
1614 st->tag_fname = alloc(MAXPATHL + 1); | |
1613 st->orgpat.pat = pat; | 1615 st->orgpat.pat = pat; |
1614 st->orgpat.len = (int)STRLEN(pat); | 1616 st->orgpat.len = (int)STRLEN(pat); |
1615 st->orgpat.regmatch.regprog = NULL; | 1617 st->orgpat.regmatch.regprog = NULL; |
1616 #ifdef FEAT_MULTI_LANG | 1618 #ifdef FEAT_MULTI_LANG |
1617 st->help_lang_find = NULL; | 1619 st->help_lang_find = NULL; |
1632 ga_init2(&st->ga_match[mtt], sizeof(char_u *), 100); | 1634 ga_init2(&st->ga_match[mtt], sizeof(char_u *), 100); |
1633 hash_init(&st->ht_match[mtt]); | 1635 hash_init(&st->ht_match[mtt]); |
1634 } | 1636 } |
1635 | 1637 |
1636 // check for out of memory situation | 1638 // check for out of memory situation |
1637 if (st->lbuf == NULL | 1639 if (st->tag_fname == NULL |
1640 || st->lbuf == NULL | |
1638 #ifdef FEAT_EMACS_TAGS | 1641 #ifdef FEAT_EMACS_TAGS |
1639 || st->ebuf == NULL | 1642 || st->ebuf == NULL |
1640 #endif | 1643 #endif |
1641 ) | 1644 ) |
1642 return FAIL; | 1645 return FAIL; |
1643 | 1646 |
1644 return OK; | 1647 return OK; |
1645 } | 1648 } |
1646 | 1649 |
1647 /* | 1650 /* |
1648 * Search for tags in the 'tag_fname' tags file. | 1651 * Search for tags matching 'st->orgpat.pat' in the 'st->tag_fname' tags file. |
1649 * Information needed to search for the tags is in the 'st' state structure. | 1652 * Information needed to search for the tags is in the 'st' state structure. |
1650 * The matching tags are returned in 'st'. | 1653 * The matching tags are returned in 'st'. |
1651 * Returns OK if successfully processed the file and FAIL on memory allocation | 1654 * Returns OK if successfully processed the file and FAIL on memory allocation |
1652 * failure. | 1655 * failure. |
1653 */ | 1656 */ |
1654 static int | 1657 static int |
1655 find_tags_in_file( | 1658 find_tags_in_file( |
1656 char_u *tag_fname, | |
1657 findtags_state_T *st, | 1659 findtags_state_T *st, |
1658 int flags, | 1660 int flags, |
1659 char_u *buf_ffname) | 1661 char_u *buf_ffname) |
1660 { | 1662 { |
1661 FILE *fp; | 1663 FILE *fp = NULL; |
1662 tagptrs_T tagp; | 1664 tagptrs_T tagp; |
1663 int is_static; // current tag line is static | 1665 int is_static; // current tag line is static |
1664 int is_current; // file name matches | 1666 int is_current; // file name matches |
1665 int eof = FALSE; // found end-of-file | 1667 int eof = FALSE; // found end-of-file |
1666 char_u *p; | 1668 char_u *p; |
1667 char_u *s; | 1669 char_u *s; |
1668 int i; | 1670 int i; |
1669 #ifdef FEAT_MULTI_LANG | 1671 #ifdef FEAT_MULTI_LANG |
1670 int help_pri = 0; | 1672 int help_pri = 0; |
1671 char_u help_lang[3]; // lang of current tags file | 1673 char_u help_lang[3] = ""; // lang of current tags file |
1672 #endif | 1674 #endif |
1673 #ifdef FEAT_TAG_BINS | 1675 #ifdef FEAT_TAG_BINS |
1674 int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value | 1676 int tag_file_sorted = NUL; // !_TAG_FILE_SORTED value |
1675 off_T filesize; | 1677 off_T filesize; |
1676 int tagcmp; | 1678 int tagcmp; |
1768 STRCPY(help_lang, "en"); | 1770 STRCPY(help_lang, "en"); |
1769 else | 1771 else |
1770 { | 1772 { |
1771 // Prefer help tags according to 'helplang'. Put the | 1773 // Prefer help tags according to 'helplang'. Put the |
1772 // two-letter language name in help_lang[]. | 1774 // two-letter language name in help_lang[]. |
1773 i = (int)STRLEN(tag_fname); | 1775 i = (int)STRLEN(st->tag_fname); |
1774 if (i > 3 && tag_fname[i - 3] == '-') | 1776 if (i > 3 && st->tag_fname[i - 3] == '-') |
1775 STRCPY(help_lang, tag_fname + i - 2); | 1777 STRCPY(help_lang, st->tag_fname + i - 2); |
1776 else | 1778 else |
1777 STRCPY(help_lang, "en"); | 1779 STRCPY(help_lang, "en"); |
1778 } | 1780 } |
1779 // When searching for a specific language skip tags files | 1781 // When searching for a specific language skip tags files |
1780 // for other languages. | 1782 // for other languages. |
1813 } | 1815 } |
1814 } | 1816 } |
1815 } | 1817 } |
1816 #endif | 1818 #endif |
1817 | 1819 |
1818 if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL) | 1820 if ((fp = mch_fopen((char *)st->tag_fname, "r")) == NULL) |
1819 return OK; | 1821 return OK; |
1820 | 1822 |
1821 if (p_verbose >= 5) | 1823 if (p_verbose >= 5) |
1822 { | 1824 { |
1823 verbose_enter(); | 1825 verbose_enter(); |
1824 smsg(_("Searching tags file %s"), tag_fname); | 1826 smsg(_("Searching tags file %s"), st->tag_fname); |
1825 verbose_leave(); | 1827 verbose_leave(); |
1826 } | 1828 } |
1827 } | 1829 } |
1828 st->did_open = TRUE; // remember that we found at least one file | 1830 st->did_open = TRUE; // remember that we found at least one file |
1829 | 1831 |
1953 if (incstack_idx) // this was an included file | 1955 if (incstack_idx) // this was an included file |
1954 { | 1956 { |
1955 --incstack_idx; | 1957 --incstack_idx; |
1956 fclose(fp); // end of this file ... | 1958 fclose(fp); // end of this file ... |
1957 fp = incstack[incstack_idx].fp; | 1959 fp = incstack[incstack_idx].fp; |
1958 STRCPY(tag_fname, incstack[incstack_idx].etag_fname); | 1960 STRCPY(st->tag_fname, incstack[incstack_idx].etag_fname); |
1959 vim_free(incstack[incstack_idx].etag_fname); | 1961 vim_free(incstack[incstack_idx].etag_fname); |
1960 is_etag = 1; // (only etags can include) | 1962 is_etag = 1; // (only etags can include) |
1961 continue; // ... continue with parent file | 1963 continue; // ... continue with parent file |
1962 } | 1964 } |
1963 else | 1965 else |
2022 if (STRNCMP(p + 1, "include", 7) == 0 | 2024 if (STRNCMP(p + 1, "include", 7) == 0 |
2023 && incstack_idx < INCSTACK_SIZE) | 2025 && incstack_idx < INCSTACK_SIZE) |
2024 { | 2026 { |
2025 // Save current "fp" and "tag_fname" in the stack. | 2027 // Save current "fp" and "tag_fname" in the stack. |
2026 if ((incstack[incstack_idx].etag_fname = | 2028 if ((incstack[incstack_idx].etag_fname = |
2027 vim_strsave(tag_fname)) != NULL) | 2029 vim_strsave(st->tag_fname)) != NULL) |
2028 { | 2030 { |
2029 char_u *fullpath_ebuf; | 2031 char_u *fullpath_ebuf; |
2030 | 2032 |
2031 incstack[incstack_idx].fp = fp; | 2033 incstack[incstack_idx].fp = fp; |
2032 fp = NULL; | 2034 fp = NULL; |
2033 | 2035 |
2034 // Figure out "tag_fname" and "fp" to use for | 2036 // Figure out "tag_fname" and "fp" to use for |
2035 // included file. | 2037 // included file. |
2036 fullpath_ebuf = expand_tag_fname(st->ebuf, | 2038 fullpath_ebuf = expand_tag_fname(st->ebuf, |
2037 tag_fname, FALSE); | 2039 st->tag_fname, FALSE); |
2038 if (fullpath_ebuf != NULL) | 2040 if (fullpath_ebuf != NULL) |
2039 { | 2041 { |
2040 fp = mch_fopen((char *)fullpath_ebuf, "r"); | 2042 fp = mch_fopen((char *)fullpath_ebuf, "r"); |
2041 if (fp != NULL) | 2043 if (fp != NULL) |
2042 { | 2044 { |
2043 if (STRLEN(fullpath_ebuf) > LSIZE) | 2045 if (STRLEN(fullpath_ebuf) > LSIZE) |
2044 semsg(_(e_tag_file_path_truncated_for_str), st->ebuf); | 2046 semsg(_(e_tag_file_path_truncated_for_str), st->ebuf); |
2045 vim_strncpy(tag_fname, fullpath_ebuf, | 2047 vim_strncpy(st->tag_fname, fullpath_ebuf, |
2046 MAXPATHL); | 2048 MAXPATHL); |
2047 ++incstack_idx; | 2049 ++incstack_idx; |
2048 is_etag = 0; // we can include anything | 2050 is_etag = 0; // we can include anything |
2049 } | 2051 } |
2050 vim_free(fullpath_ebuf); | 2052 vim_free(fullpath_ebuf); |
2183 { | 2185 { |
2184 st->lbuf_size *= 2; | 2186 st->lbuf_size *= 2; |
2185 vim_free(st->lbuf); | 2187 vim_free(st->lbuf); |
2186 st->lbuf = alloc(st->lbuf_size); | 2188 st->lbuf = alloc(st->lbuf_size); |
2187 if (st->lbuf == NULL) | 2189 if (st->lbuf == NULL) |
2190 { | |
2191 if (fp != NULL) | |
2192 fclose(fp); | |
2188 return FAIL; | 2193 return FAIL; |
2194 } | |
2189 | 2195 |
2190 #ifdef FEAT_TAG_BINS | 2196 #ifdef FEAT_TAG_BINS |
2191 if (state == TS_STEP_FORWARD) | 2197 if (state == TS_STEP_FORWARD) |
2192 // Seek to the same position to read the same line again | 2198 // Seek to the same position to read the same line again |
2193 vim_fseek(fp, search_info.curr_offset, SEEK_SET); | 2199 vim_fseek(fp, search_info.curr_offset, SEEK_SET); |
2422 // Decide in which array to store this match. | 2428 // Decide in which array to store this match. |
2423 is_current = test_for_current( | 2429 is_current = test_for_current( |
2424 #ifdef FEAT_EMACS_TAGS | 2430 #ifdef FEAT_EMACS_TAGS |
2425 is_etag, | 2431 is_etag, |
2426 #endif | 2432 #endif |
2427 tagp.fname, tagp.fname_end, tag_fname, | 2433 tagp.fname, tagp.fname_end, st->tag_fname, |
2428 buf_ffname); | 2434 buf_ffname); |
2429 #ifdef FEAT_EMACS_TAGS | 2435 #ifdef FEAT_EMACS_TAGS |
2430 is_static = FALSE; | 2436 is_static = FALSE; |
2431 if (!is_etag) // emacs tags are never static | 2437 if (!is_etag) // emacs tags are never static |
2432 #endif | 2438 #endif |
2531 get_it_again = p_sft; | 2537 get_it_again = p_sft; |
2532 } | 2538 } |
2533 } | 2539 } |
2534 else | 2540 else |
2535 { | 2541 { |
2536 size_t tag_fname_len = STRLEN(tag_fname); | 2542 size_t tag_fname_len = STRLEN(st->tag_fname); |
2537 #ifdef FEAT_EMACS_TAGS | 2543 #ifdef FEAT_EMACS_TAGS |
2538 size_t ebuf_len = 0; | 2544 size_t ebuf_len = 0; |
2539 #endif | 2545 #endif |
2540 | 2546 |
2541 // Save the tag in a buffer. | 2547 // Save the tag in a buffer. |
2559 mfp = alloc(sizeof(char_u) + len + 1); | 2565 mfp = alloc(sizeof(char_u) + len + 1); |
2560 if (mfp != NULL) | 2566 if (mfp != NULL) |
2561 { | 2567 { |
2562 p = mfp; | 2568 p = mfp; |
2563 p[0] = mtt + 1; | 2569 p[0] = mtt + 1; |
2564 STRCPY(p + 1, tag_fname); | 2570 STRCPY(p + 1, st->tag_fname); |
2565 #ifdef BACKSLASH_IN_FILENAME | 2571 #ifdef BACKSLASH_IN_FILENAME |
2566 // Ignore differences in slashes, avoid adding | 2572 // Ignore differences in slashes, avoid adding |
2567 // both path/file and path\file. | 2573 // both path/file and path\file. |
2568 slash_adjust(p + 1); | 2574 slash_adjust(p + 1); |
2569 #endif | 2575 #endif |
2630 #endif | 2636 #endif |
2631 } // forever | 2637 } // forever |
2632 | 2638 |
2633 if (line_error) | 2639 if (line_error) |
2634 { | 2640 { |
2635 semsg(_(e_format_error_in_tags_file_str), tag_fname); | 2641 semsg(_(e_format_error_in_tags_file_str), st->tag_fname); |
2636 #ifdef FEAT_CSCOPE | 2642 #ifdef FEAT_CSCOPE |
2637 if (!use_cscope) | 2643 if (!use_cscope) |
2638 #endif | 2644 #endif |
2639 semsg(_("Before byte %ld"), (long)vim_ftell(fp)); | 2645 semsg(_("Before byte %ld"), (long)vim_ftell(fp)); |
2640 st->stop_searching = TRUE; | 2646 st->stop_searching = TRUE; |
2658 | 2664 |
2659 #ifdef FEAT_TAG_BINS | 2665 #ifdef FEAT_TAG_BINS |
2660 tag_file_sorted = NUL; | 2666 tag_file_sorted = NUL; |
2661 if (sort_error) | 2667 if (sort_error) |
2662 { | 2668 { |
2663 semsg(_(e_tags_file_not_sorted_str), tag_fname); | 2669 semsg(_(e_tags_file_not_sorted_str), st->tag_fname); |
2664 sort_error = FALSE; | 2670 sort_error = FALSE; |
2665 } | 2671 } |
2666 #endif | 2672 #endif |
2667 | 2673 |
2668 /* | 2674 /* |
2761 int mincount, // MAXCOL: find all matches | 2767 int mincount, // MAXCOL: find all matches |
2762 // other: minimal number of matches | 2768 // other: minimal number of matches |
2763 char_u *buf_ffname) // name of buffer for priority | 2769 char_u *buf_ffname) // name of buffer for priority |
2764 { | 2770 { |
2765 findtags_state_T st; | 2771 findtags_state_T st; |
2766 char_u *tag_fname; // name of tag file | |
2767 tagname_T tn; // info for get_tagfname() | 2772 tagname_T tn; // info for get_tagfname() |
2768 int first_file; // trying first tag file | 2773 int first_file; // trying first tag file |
2769 int retval = FAIL; // return value | 2774 int retval = FAIL; // return value |
2770 #ifdef FEAT_TAG_BINS | 2775 #ifdef FEAT_TAG_BINS |
2771 int round; | 2776 int round; |
2809 case TC_SMART: p_ic = ignorecase_opt(pat, TRUE, TRUE); break; | 2814 case TC_SMART: p_ic = ignorecase_opt(pat, TRUE, TRUE); break; |
2810 } | 2815 } |
2811 | 2816 |
2812 help_save = curbuf->b_help; | 2817 help_save = curbuf->b_help; |
2813 | 2818 |
2814 /* | |
2815 * Allocate memory for the buffers that are used | |
2816 */ | |
2817 tag_fname = alloc(MAXPATHL + 1); | |
2818 | |
2819 // check for out of memory situation | |
2820 if (tag_fname == NULL) | |
2821 goto findtag_end; | |
2822 | |
2823 if (findtags_state_init(&st, pat, mincount) == FAIL) | 2819 if (findtags_state_init(&st, pat, mincount) == FAIL) |
2824 goto findtag_end; | 2820 goto findtag_end; |
2825 | 2821 |
2826 #ifdef FEAT_CSCOPE | 2822 #ifdef FEAT_CSCOPE |
2827 STRCPY(tag_fname, "from cscope"); // for error messages | 2823 STRCPY(st.tag_fname, "from cscope"); // for error messages |
2828 #endif | 2824 #endif |
2829 | 2825 |
2830 /* | 2826 /* |
2831 * Initialize a few variables | 2827 * Initialize a few variables |
2832 */ | 2828 */ |
2916 */ | 2912 */ |
2917 for (first_file = TRUE; | 2913 for (first_file = TRUE; |
2918 #ifdef FEAT_CSCOPE | 2914 #ifdef FEAT_CSCOPE |
2919 use_cscope || | 2915 use_cscope || |
2920 #endif | 2916 #endif |
2921 get_tagfname(&tn, first_file, tag_fname) == OK; | 2917 get_tagfname(&tn, first_file, st.tag_fname) == OK; |
2922 first_file = FALSE) | 2918 first_file = FALSE) |
2923 { | 2919 { |
2924 if (find_tags_in_file(tag_fname, &st, flags, buf_ffname) == FAIL) | 2920 if (find_tags_in_file(&st, flags, buf_ffname) == FAIL) |
2925 goto findtag_end; | 2921 goto findtag_end; |
2926 if (st.stop_searching | 2922 if (st.stop_searching |
2927 #ifdef FEAT_CSCOPE | 2923 #ifdef FEAT_CSCOPE |
2928 || use_cscope | 2924 || use_cscope |
2929 #endif | 2925 #endif |
2961 emsg(_(e_no_tags_file)); | 2957 emsg(_(e_no_tags_file)); |
2962 retval = OK; // It's OK even when no tag found | 2958 retval = OK; // It's OK even when no tag found |
2963 } | 2959 } |
2964 | 2960 |
2965 findtag_end: | 2961 findtag_end: |
2962 vim_free(st.tag_fname); | |
2966 vim_free(st.lbuf); | 2963 vim_free(st.lbuf); |
2967 vim_regfree(st.orgpat.regmatch.regprog); | 2964 vim_regfree(st.orgpat.regmatch.regprog); |
2968 vim_free(tag_fname); | |
2969 #ifdef FEAT_EMACS_TAGS | 2965 #ifdef FEAT_EMACS_TAGS |
2970 vim_free(st.ebuf); | 2966 vim_free(st.ebuf); |
2971 #endif | 2967 #endif |
2972 | 2968 |
2973 /* | 2969 /* |