# HG changeset patch # User Bram Moolenaar # Date 1553802305 -3600 # Node ID 91da8cd462eff7d83c316ce51f74a286feb21a70 # Parent 27b5c0cf863cb5693f260e03c18efaf5c05d9504 patch 8.1.1062: quickfix code is repeated commit https://github.com/vim/vim/commit/a16123a666b4656543614cb5bdaa69ea69f35d30 Author: Bram Moolenaar Date: Thu Mar 28 20:31:07 2019 +0100 patch 8.1.1062: quickfix code is repeated Problem: Quickfix code is repeated. Solution: Define FOR_ALL_QFL_ITEMS(). Move some code to separate functions. (Yegappan Lakshmanan, closes #4166) diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -195,6 +195,11 @@ static qf_info_T *ll_get_or_alloc_list(w */ #define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist) +#define FOR_ALL_QFL_ITEMS(qfl, qfp, i) \ + for (i = 0, qfp = qfl->qf_start; \ + !got_int && i < qfl->qf_count && qfp != NULL; \ + ++i, qfp = qfp->qf_next) + /* * Looking up a buffer can be slow if there are many. Remember the last one * to make this a lot faster if there are multiple matches in the same file. @@ -2148,9 +2153,7 @@ copy_loclist_entries(qf_list_T *from_qfl qfline_T *prevp; // copy all the location entries in this list - for (i = 0, from_qfp = from_qfl->qf_start; - i < from_qfl->qf_count && from_qfp != NULL; - ++i, from_qfp = from_qfp->qf_next) + FOR_ALL_QFL_ITEMS(from_qfl, from_qfp, i) { if (qf_add_entry(to_qfl, NULL, @@ -2544,9 +2547,8 @@ is_qf_entry_present(qf_list_T *qfl, qfli int i; // Search for the entry in the current list - for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; - ++i, qfp = qfp->qf_next) - if (qfp == NULL || qfp == qf_ptr) + FOR_ALL_QFL_ITEMS(qfl, qfp, i) + if (qfp == qf_ptr) break; if (i == qfl->qf_count) // Entry is not found @@ -3792,9 +3794,7 @@ qf_mark_adjust( qf_list_T *qfl = qf_get_list(qi, idx); if (!qf_list_empty(qfl)) - for (i = 0, qfp = qfl->qf_start; - i < qfl->qf_count && qfp != NULL; - ++i, qfp = qfp->qf_next) + FOR_ALL_QFL_ITEMS(qfl, qfp, i) if (qfp->qf_fnum == curbuf->b_fnum) { found_one = TRUE; @@ -4819,8 +4819,7 @@ qf_get_size(exarg_T *eap) } qfl = qf_get_curlist(qi); - for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count && qfp != NULL; - ++i, qfp = qfp->qf_next) + FOR_ALL_QFL_ITEMS(qfl, qfp, i) { if (qfp->qf_valid) { @@ -5056,6 +5055,24 @@ ex_cnext(exarg_T *eap) } /* + * Return the autocmd name for the :cfile Ex commands + */ + static char_u * +cfile_get_auname(cmdidx_T cmdidx) +{ + switch (cmdidx) + { + case CMD_cfile: return (char_u *)"cfile"; + case CMD_cgetfile: return (char_u *)"cgetfile"; + case CMD_caddfile: return (char_u *)"caddfile"; + case CMD_lfile: return (char_u *)"lfile"; + case CMD_lgetfile: return (char_u *)"lgetfile"; + case CMD_laddfile: return (char_u *)"laddfile"; + default: return NULL; + } +} + +/* * ":cfile"/":cgetfile"/":caddfile" commands. * ":lfile"/":lgetfile"/":laddfile" commands. */ @@ -5069,18 +5086,10 @@ ex_cfile(exarg_T *eap) int_u save_qfid = 0; // init for gcc int res; - switch (eap->cmdidx) - { - case CMD_cfile: au_name = (char_u *)"cfile"; break; - case CMD_cgetfile: au_name = (char_u *)"cgetfile"; break; - case CMD_caddfile: au_name = (char_u *)"caddfile"; break; - case CMD_lfile: au_name = (char_u *)"lfile"; break; - case CMD_lgetfile: au_name = (char_u *)"lgetfile"; break; - case CMD_laddfile: au_name = (char_u *)"laddfile"; break; - default: break; - } + au_name = cfile_get_auname(eap->cmdidx); if (au_name != NULL) apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf); + enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; #ifdef FEAT_BROWSE if (cmdmod.browse) @@ -5832,6 +5841,44 @@ unload_dummy_buffer(buf_T *buf, char_u * #if defined(FEAT_EVAL) || defined(PROTO) /* + * Copy the specified quickfix entry items into a new dict and appened the dict + * to 'list'. Returns OK on success. + */ + static int +get_qfline_items(qfline_T *qfp, list_T *list) +{ + int bufnum; + dict_T *dict; + char_u buf[2]; + + // Handle entries with a non-existing buffer number. + bufnum = qfp->qf_fnum; + if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) + bufnum = 0; + + if ((dict = dict_alloc()) == NULL) + return FAIL; + if (list_append_dict(list, dict) == FAIL) + return FAIL; + + buf[0] = qfp->qf_type; + buf[1] = NUL; + if (dict_add_number(dict, "bufnr", (long)bufnum) == FAIL + || dict_add_number(dict, "lnum", (long)qfp->qf_lnum) == FAIL + || dict_add_number(dict, "col", (long)qfp->qf_col) == FAIL + || dict_add_number(dict, "vcol", (long)qfp->qf_viscol) == FAIL + || dict_add_number(dict, "nr", (long)qfp->qf_nr) == FAIL + || dict_add_string(dict, "module", qfp->qf_module) == FAIL + || dict_add_string(dict, "pattern", qfp->qf_pattern) == FAIL + || dict_add_string(dict, "text", qfp->qf_text) == FAIL + || dict_add_string(dict, "type", buf) == FAIL + || dict_add_number(dict, "valid", (long)qfp->qf_valid) == FAIL) + return FAIL; + + return OK; +} + +/* * Add each quickfix error to list "list" as a dictionary. * If qf_idx is -1, use the current list. Otherwise, use the specified list. */ @@ -5840,11 +5887,8 @@ get_errorlist(qf_info_T *qi_arg, win_T * { qf_info_T *qi = qi_arg; qf_list_T *qfl; - dict_T *dict; - char_u buf[2]; qfline_T *qfp; int i; - int bufnum; if (qi == NULL) { @@ -5867,37 +5911,12 @@ get_errorlist(qf_info_T *qi_arg, win_T * if (qf_list_empty(qfl)) return FAIL; - qfp = qfl->qf_start; - for (i = 1; !got_int && i <= qfl->qf_count; ++i) - { - // Handle entries with a non-existing buffer number. - bufnum = qfp->qf_fnum; - if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) - bufnum = 0; - - if ((dict = dict_alloc()) == NULL) - return FAIL; - if (list_append_dict(list, dict) == FAIL) + FOR_ALL_QFL_ITEMS(qfl, qfp, i) + { + if (get_qfline_items(qfp, list) == FAIL) return FAIL; - - buf[0] = qfp->qf_type; - buf[1] = NUL; - if ( dict_add_number(dict, "bufnr", (long)bufnum) == FAIL - || dict_add_number(dict, "lnum", (long)qfp->qf_lnum) == FAIL - || dict_add_number(dict, "col", (long)qfp->qf_col) == FAIL - || dict_add_number(dict, "vcol", (long)qfp->qf_viscol) == FAIL - || dict_add_number(dict, "nr", (long)qfp->qf_nr) == FAIL - || dict_add_string(dict, "module", qfp->qf_module) == FAIL - || dict_add_string(dict, "pattern", qfp->qf_pattern) == FAIL - || dict_add_string(dict, "text", qfp->qf_text) == FAIL - || dict_add_string(dict, "type", buf) == FAIL - || dict_add_number(dict, "valid", (long)qfp->qf_valid) == FAIL) - return FAIL; - - qfp = qfp->qf_next; - if (qfp == NULL) - break; - } + } + return OK; } @@ -6842,6 +6861,74 @@ set_ref_in_quickfix(int copyID) #endif /* + * Return the autocmd name for the :cbuffer Ex commands + */ + static char_u * +cbuffer_get_auname(cmdidx_T cmdidx) +{ + switch (cmdidx) + { + case CMD_cbuffer: return (char_u *)"cbuffer"; + case CMD_cgetbuffer: return (char_u *)"cgetbuffer"; + case CMD_caddbuffer: return (char_u *)"caddbuffer"; + case CMD_lbuffer: return (char_u *)"lbuffer"; + case CMD_lgetbuffer: return (char_u *)"lgetbuffer"; + case CMD_laddbuffer: return (char_u *)"laddbuffer"; + default: return NULL; + } +} + +/* + * Process and validate the arguments passed to the :cbuffer, :caddbuffer, + * :cgetbuffer, :lbuffer, :laddbuffer, :lgetbuffer Ex commands. + */ + static int +cbuffer_process_args( + exarg_T *eap, + buf_T **bufp, + linenr_T *line1, + linenr_T *line2) +{ + buf_T *buf = NULL; + + if (*eap->arg == NUL) + buf = curbuf; + else if (*skipwhite(skipdigits(eap->arg)) == NUL) + buf = buflist_findnr(atoi((char *)eap->arg)); + + if (buf == NULL) + { + emsg(_(e_invarg)); + return FAIL; + } + + if (buf->b_ml.ml_mfp == NULL) + { + emsg(_("E681: Buffer is not loaded")); + return FAIL; + } + + if (eap->addr_count == 0) + { + eap->line1 = 1; + eap->line2 = buf->b_ml.ml_line_count; + } + + if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count + || eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count) + { + emsg(_(e_invrange)); + return FAIL; + } + + *line1 = eap->line1; + *line2 = eap->line2; + *bufp = buf; + + return OK; +} + +/* * ":[range]cbuffer [bufnr]" command. * ":[range]caddbuffer [bufnr]" command. * ":[range]cgetbuffer [bufnr]" command. @@ -6858,19 +6945,13 @@ ex_cbuffer(exarg_T *eap) int res; int_u save_qfid; win_T *wp = NULL; - - switch (eap->cmdidx) - { - case CMD_cbuffer: au_name = (char_u *)"cbuffer"; break; - case CMD_cgetbuffer: au_name = (char_u *)"cgetbuffer"; break; - case CMD_caddbuffer: au_name = (char_u *)"caddbuffer"; break; - case CMD_lbuffer: au_name = (char_u *)"lbuffer"; break; - case CMD_lgetbuffer: au_name = (char_u *)"lgetbuffer"; break; - case CMD_laddbuffer: au_name = (char_u *)"laddbuffer"; break; - default: break; - } + char_u *qf_title; + linenr_T line1; + linenr_T line2; + + au_name = cbuffer_get_auname(eap->cmdidx); if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, - curbuf->b_fname, TRUE, curbuf)) + curbuf->b_fname, TRUE, curbuf)) { #ifdef FEAT_EVAL if (aborting()) @@ -6887,79 +6968,78 @@ ex_cbuffer(exarg_T *eap) wp = curwin; } - if (*eap->arg == NUL) - buf = curbuf; - else if (*skipwhite(skipdigits(eap->arg)) == NUL) - buf = buflist_findnr(atoi((char *)eap->arg)); - if (buf == NULL) - emsg(_(e_invarg)); - else if (buf->b_ml.ml_mfp == NULL) - emsg(_("E681: Buffer is not loaded")); - else - { - if (eap->addr_count == 0) - { - eap->line1 = 1; - eap->line2 = buf->b_ml.ml_line_count; - } - if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count - || eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count) - emsg(_(e_invrange)); - else - { - char_u *qf_title = qf_cmdtitle(*eap->cmdlinep); - - if (buf->b_sfname) - { - vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", - (char *)qf_title, (char *)buf->b_sfname); - qf_title = IObuff; - } - - incr_quickfix_busy(); - - res = qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm, - (eap->cmdidx != CMD_caddbuffer - && eap->cmdidx != CMD_laddbuffer), - eap->line1, eap->line2, - qf_title, NULL); - if (qf_stack_empty(qi)) - { - decr_quickfix_busy(); - return; - } - if (res >= 0) - qf_list_changed(qf_get_curlist(qi)); - - // Remember the current quickfix list identifier, so that we can - // check for autocommands changing the current quickfix list. - save_qfid = qf_get_curlist(qi)->qf_id; - if (au_name != NULL) - { - buf_T *curbuf_old = curbuf; - - apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, - curbuf->b_fname, TRUE, curbuf); - if (curbuf != curbuf_old) - // Autocommands changed buffer, don't jump now, "qi" may - // be invalid. - res = 0; - } - // Jump to the first error for a new list and if autocmds didn't - // free the list. - if (res > 0 && (eap->cmdidx == CMD_cbuffer || - eap->cmdidx == CMD_lbuffer) - && qflist_valid(wp, save_qfid)) - // display the first error - qf_jump_first(qi, save_qfid, eap->forceit); - - decr_quickfix_busy(); - } - } + if (cbuffer_process_args(eap, &buf, &line1, &line2) == FAIL) + return; + + qf_title = qf_cmdtitle(*eap->cmdlinep); + + if (buf->b_sfname) + { + vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", + (char *)qf_title, (char *)buf->b_sfname); + qf_title = IObuff; + } + + incr_quickfix_busy(); + + res = qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm, + (eap->cmdidx != CMD_caddbuffer + && eap->cmdidx != CMD_laddbuffer), + line1, line2, + qf_title, NULL); + if (qf_stack_empty(qi)) + { + decr_quickfix_busy(); + return; + } + if (res >= 0) + qf_list_changed(qf_get_curlist(qi)); + + // Remember the current quickfix list identifier, so that we can + // check for autocommands changing the current quickfix list. + save_qfid = qf_get_curlist(qi)->qf_id; + if (au_name != NULL) + { + buf_T *curbuf_old = curbuf; + + apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, + TRUE, curbuf); + if (curbuf != curbuf_old) + // Autocommands changed buffer, don't jump now, "qi" may + // be invalid. + res = 0; + } + // Jump to the first error for a new list and if autocmds didn't + // free the list. + if (res > 0 && (eap->cmdidx == CMD_cbuffer || + eap->cmdidx == CMD_lbuffer) + && qflist_valid(wp, save_qfid)) + // display the first error + qf_jump_first(qi, save_qfid, eap->forceit); + + decr_quickfix_busy(); } #if defined(FEAT_EVAL) || defined(PROTO) /* + * Return the autocmd name for the :cexpr Ex commands. + */ + static char_u * +cexpr_get_auname(cmdidx_T cmdidx) +{ + switch (cmdidx) + { + case CMD_cexpr: return (char_u *)"cexpr"; + case CMD_cgetexpr: return (char_u *)"cgetexpr"; + case CMD_caddexpr: return (char_u *)"caddexpr"; + case CMD_lexpr: return (char_u *)"lexpr"; + case CMD_lgetexpr: return (char_u *)"lgetexpr"; + case CMD_laddexpr: return (char_u *)"laddexpr"; + default: return NULL; + } +} + +/* * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command. * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command. */ @@ -6973,16 +7053,7 @@ ex_cexpr(exarg_T *eap) int_u save_qfid; win_T *wp = NULL; - switch (eap->cmdidx) - { - case CMD_cexpr: au_name = (char_u *)"cexpr"; break; - case CMD_cgetexpr: au_name = (char_u *)"cgetexpr"; break; - case CMD_caddexpr: au_name = (char_u *)"caddexpr"; break; - case CMD_lexpr: au_name = (char_u *)"lexpr"; break; - case CMD_lgetexpr: au_name = (char_u *)"lgetexpr"; break; - case CMD_laddexpr: au_name = (char_u *)"laddexpr"; break; - default: break; - } + au_name = cexpr_get_auname(eap->cmdidx); if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, curbuf->b_fname, TRUE, curbuf)) { @@ -7257,10 +7328,6 @@ ex_helpgrep(exarg_T *eap) #endif } - // Make 'cpoptions' empty, the 'l' flag should not be used here. - save_cpo = p_cpo; - p_cpo = empty_option; - if (is_loclist_cmd(eap->cmdidx)) { qi = hgr_get_ll(&new_qi); @@ -7268,6 +7335,10 @@ ex_helpgrep(exarg_T *eap) return; } + // Make 'cpoptions' empty, the 'l' flag should not be used here. + save_cpo = p_cpo; + p_cpo = empty_option; + incr_quickfix_busy(); #ifdef FEAT_MULTI_LANG diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -776,6 +776,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1062, +/**/ 1061, /**/ 1060,