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;