To: vim_dev@googlegroups.com Subject: Patch 8.1.1062 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1062 Problem: Quickfix code is repeated. Solution: Define FOR_ALL_QFL_ITEMS(). Move some code to separate functions. (Yegappan Lakshmanan, closes #4166) Files: src/quickfix.c *** ../vim-8.1.1061/src/quickfix.c 2019-03-22 14:16:02.877160892 +0100 --- src/quickfix.c 2019-03-28 20:29:41.737770187 +0100 *************** *** 195,200 **** --- 195,205 ---- */ #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,2156 **** 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) { if (qf_add_entry(to_qfl, NULL, --- 2153,2159 ---- qfline_T *prevp; // copy all the location entries in this list ! FOR_ALL_QFL_ITEMS(from_qfl, from_qfp, i) { if (qf_add_entry(to_qfl, NULL, *************** *** 2544,2552 **** 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) break; if (i == qfl->qf_count) // Entry is not found --- 2547,2554 ---- int i; // Search for the entry in the current list ! FOR_ALL_QFL_ITEMS(qfl, qfp, i) ! if (qfp == qf_ptr) break; if (i == qfl->qf_count) // Entry is not found *************** *** 3792,3800 **** 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) if (qfp->qf_fnum == curbuf->b_fnum) { found_one = TRUE; --- 3794,3800 ---- qf_list_T *qfl = qf_get_list(qi, idx); if (!qf_list_empty(qfl)) ! FOR_ALL_QFL_ITEMS(qfl, qfp, i) if (qfp->qf_fnum == curbuf->b_fnum) { found_one = TRUE; *************** *** 4819,4826 **** } qfl = qf_get_curlist(qi); ! for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count && qfp != NULL; ! ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) { --- 4819,4825 ---- } qfl = qf_get_curlist(qi); ! FOR_ALL_QFL_ITEMS(qfl, qfp, i) { if (qfp->qf_valid) { *************** *** 5056,5061 **** --- 5055,5078 ---- } /* + * 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,5086 **** 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; ! } 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) --- 5086,5095 ---- int_u save_qfid = 0; // init for gcc int res; ! 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,5837 **** --- 5841,5884 ---- #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,5850 **** { 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) { --- 5887,5894 ---- *************** *** 5867,5903 **** 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) - 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; } --- 5911,5922 ---- if (qf_list_empty(qfl)) return FAIL; ! FOR_ALL_QFL_ITEMS(qfl, qfp, i) { ! if (get_qfline_items(qfp, list) == FAIL) return FAIL; } + return OK; } *************** *** 6842,6847 **** --- 6861,6934 ---- #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,6876 **** 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; ! } if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, ! curbuf->b_fname, TRUE, curbuf)) { #ifdef FEAT_EVAL if (aborting()) --- 6945,6957 ---- int res; int_u save_qfid; win_T *wp = NULL; + 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)) { #ifdef FEAT_EVAL if (aborting()) *************** *** 6887,6965 **** 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 defined(FEAT_EVAL) || defined(PROTO) /* * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command. * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command. */ --- 6968,7045 ---- wp = curwin; } ! 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,6988 **** 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; ! } if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, curbuf->b_fname, TRUE, curbuf)) { --- 7053,7059 ---- int_u save_qfid; win_T *wp = NULL; ! au_name = cexpr_get_auname(eap->cmdidx); if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, curbuf->b_fname, TRUE, curbuf)) { *************** *** 7257,7266 **** #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); --- 7328,7333 ---- *************** *** 7268,7273 **** --- 7335,7344 ---- 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 *** ../vim-8.1.1061/src/version.c 2019-03-27 22:53:49.919226659 +0100 --- src/version.c 2019-03-28 20:30:09.001593202 +0100 *************** *** 777,778 **** --- 777,780 ---- { /* Add new patch number below this line */ + /**/ + 1062, /**/ -- The coffee just wasn't strong enough to defend itself -- Tom Waits /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///