Mercurial > vim
comparison src/quickfix.c @ 16186:e12336bb8ced v8.1.1098
patch 8.1.1098: quickfix code duplication
commit https://github.com/vim/vim/commit/95946f1209ad088bfe55c83256c299156c11d8e0
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Mar 31 15:31:59 2019 +0200
patch 8.1.1098: quickfix code duplication
Problem: Quickfix code duplication.
Solution: Refactor the qf_init_ext() function. (Yegappan Lakshmanan,
closes #4193)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 31 Mar 2019 15:45:05 +0200 |
parents | 91da8cd462ef |
children | 4202f556aefe |
comparison
equal
deleted
inserted
replaced
16185:8280f40fca93 | 16186:e12336bb8ced |
---|---|
193 * Return location list for window 'wp' | 193 * Return location list for window 'wp' |
194 * For location list window, return the referenced location list | 194 * For location list window, return the referenced location list |
195 */ | 195 */ |
196 #define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist) | 196 #define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist) |
197 | 197 |
198 // Macro to loop through all the items in a quickfix list | |
199 // Quickfix item index starts from 1, so i below starts at 1 | |
198 #define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \ | 200 #define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \ |
199 for (i = 0, qfp = qfl->qf_start; \ | 201 for (i = 1, qfp = qfl->qf_start; \ |
200 !got_int && i < qfl->qf_count && qfp != NULL; \ | 202 !got_int && i <= qfl->qf_count && qfp != NULL; \ |
201 ++i, qfp = qfp->qf_next) | 203 ++i, qfp = qfp->qf_next) |
202 | 204 |
203 /* | 205 /* |
204 * Looking up a buffer can be slow if there are many. Remember the last one | 206 * Looking up a buffer can be slow if there are many. Remember the last one |
205 * to make this a lot faster if there are multiple matches in the same file. | 207 * to make this a lot faster if there are multiple matches in the same file. |
1583 if (pstate->vc.vc_type != CONV_NONE) | 1585 if (pstate->vc.vc_type != CONV_NONE) |
1584 convert_setup(&pstate->vc, NULL, NULL); | 1586 convert_setup(&pstate->vc, NULL, NULL); |
1585 } | 1587 } |
1586 | 1588 |
1587 /* | 1589 /* |
1590 * Process the next line from a file/buffer/list/string and add it | |
1591 * to the quickfix list 'qfl'. | |
1592 */ | |
1593 static int | |
1594 qf_init_process_nextline( | |
1595 qf_list_T *qfl, | |
1596 efm_T *fmt_first, | |
1597 qfstate_T *state, | |
1598 qffields_T *fields) | |
1599 { | |
1600 int status; | |
1601 | |
1602 // Get the next line from a file/buffer/list/string | |
1603 status = qf_get_nextline(state); | |
1604 if (status != QF_OK) | |
1605 return status; | |
1606 | |
1607 status = qf_parse_line(qfl, state->linebuf, state->linelen, | |
1608 fmt_first, fields); | |
1609 if (status != QF_OK) | |
1610 return status; | |
1611 | |
1612 return qf_add_entry(qfl, | |
1613 qfl->qf_directory, | |
1614 (*fields->namebuf || qfl->qf_directory != NULL) | |
1615 ? fields->namebuf | |
1616 : ((qfl->qf_currfile != NULL && fields->valid) | |
1617 ? qfl->qf_currfile : (char_u *)NULL), | |
1618 fields->module, | |
1619 0, | |
1620 fields->errmsg, | |
1621 fields->lnum, | |
1622 fields->col, | |
1623 fields->use_viscol, | |
1624 fields->pattern, | |
1625 fields->enr, | |
1626 fields->type, | |
1627 fields->valid); | |
1628 } | |
1629 | |
1630 /* | |
1588 * Read the errorfile "efile" into memory, line by line, building the error | 1631 * Read the errorfile "efile" into memory, line by line, building the error |
1589 * list. | 1632 * list. |
1590 * Alternative: when "efile" is NULL read errors from buffer "buf". | 1633 * Alternative: when "efile" is NULL read errors from buffer "buf". |
1591 * Alternative: when "tv" is not NULL get errors from the string or list. | 1634 * Alternative: when "tv" is not NULL get errors from the string or list. |
1592 * Always use 'errorformat' from "buf" if there is a local value. | 1635 * Always use 'errorformat' from "buf" if there is a local value. |
1674 | 1717 |
1675 // Read the lines in the error file one by one. | 1718 // Read the lines in the error file one by one. |
1676 // Try to recognize one of the error formats in each line. | 1719 // Try to recognize one of the error formats in each line. |
1677 while (!got_int) | 1720 while (!got_int) |
1678 { | 1721 { |
1679 // Get the next line from a file/buffer/list/string | 1722 status = qf_init_process_nextline(qfl, fmt_first, &state, &fields); |
1680 status = qf_get_nextline(&state); | |
1681 if (status == QF_NOMEM) // memory alloc failure | 1723 if (status == QF_NOMEM) // memory alloc failure |
1682 goto qf_init_end; | 1724 goto qf_init_end; |
1683 if (status == QF_END_OF_INPUT) // end of input | 1725 if (status == QF_END_OF_INPUT) // end of input |
1684 break; | 1726 break; |
1685 | |
1686 status = qf_parse_line(qfl, state.linebuf, state.linelen, | |
1687 fmt_first, &fields); | |
1688 if (status == QF_FAIL) | 1727 if (status == QF_FAIL) |
1689 goto error2; | 1728 goto error2; |
1690 if (status == QF_NOMEM) | 1729 |
1691 goto qf_init_end; | |
1692 if (status == QF_IGNORE_LINE) | |
1693 continue; | |
1694 | |
1695 if (qf_add_entry(qfl, | |
1696 qfl->qf_directory, | |
1697 (*fields.namebuf || qfl->qf_directory != NULL) | |
1698 ? fields.namebuf | |
1699 : ((qfl->qf_currfile != NULL && fields.valid) | |
1700 ? qfl->qf_currfile : (char_u *)NULL), | |
1701 fields.module, | |
1702 0, | |
1703 fields.errmsg, | |
1704 fields.lnum, | |
1705 fields.col, | |
1706 fields.use_viscol, | |
1707 fields.pattern, | |
1708 fields.enr, | |
1709 fields.type, | |
1710 fields.valid) == FAIL) | |
1711 goto error2; | |
1712 line_breakcheck(); | 1730 line_breakcheck(); |
1713 } | 1731 } |
1714 if (state.fd == NULL || !ferror(state.fd)) | 1732 if (state.fd == NULL || !ferror(state.fd)) |
1715 { | 1733 { |
1716 if (qfl->qf_index == 0) | 1734 if (qfl->qf_index == 0) |
2011 } | 2029 } |
2012 #endif | 2030 #endif |
2013 | 2031 |
2014 /* | 2032 /* |
2015 * Add an entry to the end of the list of errors. | 2033 * Add an entry to the end of the list of errors. |
2016 * Returns OK or FAIL. | 2034 * Returns QF_OK or QF_FAIL. |
2017 */ | 2035 */ |
2018 static int | 2036 static int |
2019 qf_add_entry( | 2037 qf_add_entry( |
2020 qf_list_T *qfl, // quickfix list entry | 2038 qf_list_T *qfl, // quickfix list entry |
2021 char_u *dir, // optional directory name | 2039 char_u *dir, // optional directory name |
2033 { | 2051 { |
2034 qfline_T *qfp; | 2052 qfline_T *qfp; |
2035 qfline_T **lastp; // pointer to qf_last or NULL | 2053 qfline_T **lastp; // pointer to qf_last or NULL |
2036 | 2054 |
2037 if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL) | 2055 if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL) |
2038 return FAIL; | 2056 return QF_FAIL; |
2039 if (bufnum != 0) | 2057 if (bufnum != 0) |
2040 { | 2058 { |
2041 buf_T *buf = buflist_findnr(bufnum); | 2059 buf_T *buf = buflist_findnr(bufnum); |
2042 | 2060 |
2043 qfp->qf_fnum = bufnum; | 2061 qfp->qf_fnum = bufnum; |
2048 else | 2066 else |
2049 qfp->qf_fnum = qf_get_fnum(qfl, dir, fname); | 2067 qfp->qf_fnum = qf_get_fnum(qfl, dir, fname); |
2050 if ((qfp->qf_text = vim_strsave(mesg)) == NULL) | 2068 if ((qfp->qf_text = vim_strsave(mesg)) == NULL) |
2051 { | 2069 { |
2052 vim_free(qfp); | 2070 vim_free(qfp); |
2053 return FAIL; | 2071 return QF_FAIL; |
2054 } | 2072 } |
2055 qfp->qf_lnum = lnum; | 2073 qfp->qf_lnum = lnum; |
2056 qfp->qf_col = col; | 2074 qfp->qf_col = col; |
2057 qfp->qf_viscol = vis_col; | 2075 qfp->qf_viscol = vis_col; |
2058 if (pattern == NULL || *pattern == NUL) | 2076 if (pattern == NULL || *pattern == NUL) |
2059 qfp->qf_pattern = NULL; | 2077 qfp->qf_pattern = NULL; |
2060 else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL) | 2078 else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL) |
2061 { | 2079 { |
2062 vim_free(qfp->qf_text); | 2080 vim_free(qfp->qf_text); |
2063 vim_free(qfp); | 2081 vim_free(qfp); |
2064 return FAIL; | 2082 return QF_FAIL; |
2065 } | 2083 } |
2066 if (module == NULL || *module == NUL) | 2084 if (module == NULL || *module == NUL) |
2067 qfp->qf_module = NULL; | 2085 qfp->qf_module = NULL; |
2068 else if ((qfp->qf_module = vim_strsave(module)) == NULL) | 2086 else if ((qfp->qf_module = vim_strsave(module)) == NULL) |
2069 { | 2087 { |
2070 vim_free(qfp->qf_text); | 2088 vim_free(qfp->qf_text); |
2071 vim_free(qfp->qf_pattern); | 2089 vim_free(qfp->qf_pattern); |
2072 vim_free(qfp); | 2090 vim_free(qfp); |
2073 return FAIL; | 2091 return QF_FAIL; |
2074 } | 2092 } |
2075 qfp->qf_nr = nr; | 2093 qfp->qf_nr = nr; |
2076 if (type != 1 && !vim_isprintc(type)) // only printable chars allowed | 2094 if (type != 1 && !vim_isprintc(type)) // only printable chars allowed |
2077 type = 0; | 2095 type = 0; |
2078 qfp->qf_type = type; | 2096 qfp->qf_type = type; |
2099 { | 2117 { |
2100 qfl->qf_index = qfl->qf_count; | 2118 qfl->qf_index = qfl->qf_count; |
2101 qfl->qf_ptr = qfp; | 2119 qfl->qf_ptr = qfp; |
2102 } | 2120 } |
2103 | 2121 |
2104 return OK; | 2122 return QF_OK; |
2105 } | 2123 } |
2106 | 2124 |
2107 /* | 2125 /* |
2108 * Allocate a new quickfix/location list stack | 2126 * Allocate a new quickfix/location list stack |
2109 */ | 2127 */ |
2165 from_qfp->qf_col, | 2183 from_qfp->qf_col, |
2166 from_qfp->qf_viscol, | 2184 from_qfp->qf_viscol, |
2167 from_qfp->qf_pattern, | 2185 from_qfp->qf_pattern, |
2168 from_qfp->qf_nr, | 2186 from_qfp->qf_nr, |
2169 0, | 2187 0, |
2170 from_qfp->qf_valid) == FAIL) | 2188 from_qfp->qf_valid) == QF_FAIL) |
2171 return FAIL; | 2189 return FAIL; |
2172 | 2190 |
2173 // qf_add_entry() will not set the qf_num field, as the | 2191 // qf_add_entry() will not set the qf_num field, as the |
2174 // directory and file names are not supplied. So the qf_fnum | 2192 // directory and file names are not supplied. So the qf_fnum |
2175 // field is copied here. | 2193 // field is copied here. |
2549 // Search for the entry in the current list | 2567 // Search for the entry in the current list |
2550 FOR_ALL_QFL_ITEMS(qfl, qfp, i) | 2568 FOR_ALL_QFL_ITEMS(qfl, qfp, i) |
2551 if (qfp == qf_ptr) | 2569 if (qfp == qf_ptr) |
2552 break; | 2570 break; |
2553 | 2571 |
2554 if (i == qfl->qf_count) // Entry is not found | 2572 if (i > qfl->qf_count) // Entry is not found |
2555 return FALSE; | 2573 return FALSE; |
2556 | 2574 |
2557 return TRUE; | 2575 return TRUE; |
2558 } | 2576 } |
2559 | 2577 |
3552 if (qfLineAttr == 0) | 3570 if (qfLineAttr == 0) |
3553 qfLineAttr = HL_ATTR(HLF_N); | 3571 qfLineAttr = HL_ATTR(HLF_N); |
3554 | 3572 |
3555 if (qfl->qf_nonevalid) | 3573 if (qfl->qf_nonevalid) |
3556 all = TRUE; | 3574 all = TRUE; |
3557 qfp = qfl->qf_start; | 3575 FOR_ALL_QFL_ITEMS(qfl, qfp, i) |
3558 for (i = 1; !got_int && i <= qfl->qf_count; ) | |
3559 { | 3576 { |
3560 if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) | 3577 if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) |
3561 { | |
3562 if (got_int) | |
3563 break; | |
3564 | |
3565 qf_list_entry(qfp, i, i == qfl->qf_index); | 3578 qf_list_entry(qfp, i, i == qfl->qf_index); |
3566 } | 3579 |
3567 | |
3568 qfp = qfp->qf_next; | |
3569 if (qfp == NULL) | |
3570 break; | |
3571 ++i; | |
3572 ui_breakcheck(); | 3580 ui_breakcheck(); |
3573 } | 3581 } |
3574 } | 3582 } |
3575 | 3583 |
3576 /* | 3584 /* |
4913 * For :cfdo and :lfdo returns the 'n'th valid file entry. | 4921 * For :cfdo and :lfdo returns the 'n'th valid file entry. |
4914 */ | 4922 */ |
4915 static int | 4923 static int |
4916 qf_get_nth_valid_entry(qf_list_T *qfl, int n, int fdo) | 4924 qf_get_nth_valid_entry(qf_list_T *qfl, int n, int fdo) |
4917 { | 4925 { |
4918 qfline_T *qfp = qfl->qf_start; | 4926 qfline_T *qfp; |
4919 int i, eidx; | 4927 int i, eidx; |
4920 int prev_fnum = 0; | 4928 int prev_fnum = 0; |
4921 | 4929 |
4922 // check if the list has valid errors | 4930 // check if the list has valid errors |
4923 if (qfl->qf_count <= 0 || qfl->qf_nonevalid) | 4931 if (qfl->qf_count <= 0 || qfl->qf_nonevalid) |
4924 return 1; | 4932 return 1; |
4925 | 4933 |
4926 for (i = 1, eidx = 0; i <= qfl->qf_count && qfp != NULL; | 4934 eidx = 0; |
4927 i++, qfp = qfp->qf_next) | 4935 FOR_ALL_QFL_ITEMS(qfl, qfp, i) |
4928 { | 4936 { |
4929 if (qfp->qf_valid) | 4937 if (qfp->qf_valid) |
4930 { | 4938 { |
4931 if (fdo) | 4939 if (fdo) |
4932 { | 4940 { |
5328 FALSE, // vis_col | 5336 FALSE, // vis_col |
5329 NULL, // search pattern | 5337 NULL, // search pattern |
5330 0, // nr | 5338 0, // nr |
5331 0, // type | 5339 0, // type |
5332 TRUE // valid | 5340 TRUE // valid |
5333 ) == FAIL) | 5341 ) == QF_FAIL) |
5334 { | 5342 { |
5335 got_int = TRUE; | 5343 got_int = TRUE; |
5336 break; | 5344 break; |
5337 } | 5345 } |
5338 found_match = TRUE; | 5346 found_match = TRUE; |
6432 if (d == NULL) | 6440 if (d == NULL) |
6433 continue; | 6441 continue; |
6434 | 6442 |
6435 retval = qf_add_entry_from_dict(qfl, d, li == list->lv_first, | 6443 retval = qf_add_entry_from_dict(qfl, d, li == list->lv_first, |
6436 &valid_entry); | 6444 &valid_entry); |
6437 if (retval == FAIL) | 6445 if (retval == QF_FAIL) |
6438 break; | 6446 break; |
6439 } | 6447 } |
6440 | 6448 |
6441 // Check if any valid error entries are added to the list. | 6449 // Check if any valid error entries are added to the list. |
6442 if (valid_entry) | 6450 if (valid_entry) |
6742 else if (qfwin != NULL) | 6750 else if (qfwin != NULL) |
6743 { | 6751 { |
6744 // If the location list window is open, then create a new empty | 6752 // If the location list window is open, then create a new empty |
6745 // location list | 6753 // location list |
6746 qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION); | 6754 qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION); |
6747 new_ll->qf_bufnr = qfwin->w_buffer->b_fnum; | 6755 |
6748 | 6756 if (new_ll != NULL) |
6749 // first free the list reference in the location list window | 6757 { |
6750 ll_free_all(&qfwin->w_llist_ref); | 6758 new_ll->qf_bufnr = qfwin->w_buffer->b_fnum; |
6751 | 6759 |
6752 qfwin->w_llist_ref = new_ll; | 6760 // first free the list reference in the location list window |
6753 if (wp != qfwin) | 6761 ll_free_all(&qfwin->w_llist_ref); |
6754 win_set_loclist(wp, new_ll); | 6762 |
6763 qfwin->w_llist_ref = new_ll; | |
6764 if (wp != qfwin) | |
6765 win_set_loclist(wp, new_ll); | |
6766 } | |
6755 } | 6767 } |
6756 } | 6768 } |
6757 | 6769 |
6758 /* | 6770 /* |
6759 * Populate the quickfix list with the items supplied in the list | 6771 * Populate the quickfix list with the items supplied in the list |
7201 FALSE, // vis_col | 7213 FALSE, // vis_col |
7202 NULL, // search pattern | 7214 NULL, // search pattern |
7203 0, // nr | 7215 0, // nr |
7204 1, // type | 7216 1, // type |
7205 TRUE // valid | 7217 TRUE // valid |
7206 ) == FAIL) | 7218 ) == QF_FAIL) |
7207 { | 7219 { |
7208 got_int = TRUE; | 7220 got_int = TRUE; |
7209 if (line != IObuff) | 7221 if (line != IObuff) |
7210 vim_free(line); | 7222 vim_free(line); |
7211 break; | 7223 break; |