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 /*