To: vim_dev@googlegroups.com Subject: Patch 8.1.0469 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0469 Problem: Too often indexing in qf_lists[]. Solution: Use a qf_list_T pointer. (Yegappan Lakshmanan) Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.1.0468/src/quickfix.c 2018-10-07 20:26:15.834185143 +0200 --- src/quickfix.c 2018-10-11 17:37:51.185959011 +0200 *************** *** 1729,1735 **** if (!adding) { // Error when creating a new list. Free the new list ! qf_free(&qi->qf_lists[qi->qf_curlist]); qi->qf_listcount--; if (qi->qf_curlist > 0) --qi->qf_curlist; --- 1729,1735 ---- if (!adding) { // Error when creating a new list. Free the new list ! qf_free(qfl); qi->qf_listcount--; if (qi->qf_curlist > 0) --qi->qf_curlist; *************** *** 1812,1817 **** --- 1812,1818 ---- qf_new_list(qf_info_T *qi, char_u *qf_title) { int i; + qf_list_T *qfl; // If the current entry is not the last entry, delete entries beyond // the current entry. This makes it possible to browse in a tree-like *************** *** 1830,1838 **** } else qi->qf_curlist = qi->qf_listcount++; ! vim_memset(&qi->qf_lists[qi->qf_curlist], 0, (size_t)(sizeof(qf_list_T))); ! qf_store_title(&qi->qf_lists[qi->qf_curlist], qf_title); ! qi->qf_lists[qi->qf_curlist].qf_id = ++last_qf_id; } /* --- 1831,1840 ---- } else qi->qf_curlist = qi->qf_listcount++; ! qfl = &qi->qf_lists[qi->qf_curlist]; ! vim_memset(qfl, 0, (size_t)(sizeof(qf_list_T))); ! qf_store_title(qfl, qf_title); ! qfl->qf_id = ++last_qf_id; } /* *************** *** 2149,2154 **** --- 2151,2157 ---- static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory, char_u *fname) { + qf_list_T *qfl = &qi->qf_lists[qf_idx]; char_u *ptr = NULL; buf_T *buf; char_u *bufname; *************** *** 2174,2180 **** if (mch_getperm(ptr) < 0) { vim_free(ptr); ! directory = qf_guess_filepath(&qi->qf_lists[qf_idx], fname); if (directory) ptr = concat_fnames(directory, fname, TRUE); else --- 2177,2183 ---- if (mch_getperm(ptr) < 0) { vim_free(ptr); ! directory = qf_guess_filepath(qfl, fname); if (directory) ptr = concat_fnames(directory, fname, TRUE); else *************** *** 3757,3762 **** --- 3760,3766 ---- ex_cwindow(exarg_T *eap) { qf_info_T *qi = &ql_info; + qf_list_T *qfl; win_T *win; if (is_loclist_cmd(eap->cmdidx)) *************** *** 3766,3771 **** --- 3770,3777 ---- return; } + qfl = &qi->qf_lists[qi->qf_curlist]; + // Look for an existing quickfix window. win = qf_find_win(qi); *************** *** 3773,3779 **** // close the window. If a quickfix window is not open, then open // it if we have errors; otherwise, leave it closed. if (qf_stack_empty(qi) ! || qi->qf_lists[qi->qf_curlist].qf_nonevalid || qf_list_empty(qi, qi->qf_curlist)) { if (win != NULL) --- 3779,3785 ---- // close the window. If a quickfix window is not open, then open // it if we have errors; otherwise, leave it closed. if (qf_stack_empty(qi) ! || qfl->qf_nonevalid || qf_list_empty(qi, qi->qf_curlist)) { if (win != NULL) *************** *** 3930,3935 **** --- 3936,3942 ---- ex_copen(exarg_T *eap) { qf_info_T *qi = &ql_info; + qf_list_T *qfl; int height; int status = FAIL; *************** *** 3961,3972 **** if (qf_open_new_cwindow(qi, height) == FAIL) return; ! qf_set_title_var(&qi->qf_lists[qi->qf_curlist]); // Fill the buffer with the quickfix list. qf_fill_buffer(qi, curbuf, NULL); ! curwin->w_cursor.lnum = qi->qf_lists[qi->qf_curlist].qf_index; curwin->w_cursor.col = 0; check_cursor(); update_topline(); // scroll to show the line --- 3968,3980 ---- if (qf_open_new_cwindow(qi, height) == FAIL) return; ! qfl = &qi->qf_lists[qi->qf_curlist]; ! qf_set_title_var(qfl); // Fill the buffer with the quickfix list. qf_fill_buffer(qi, curbuf, NULL); ! curwin->w_cursor.lnum = qfl->qf_index; curwin->w_cursor.col = 0; check_cursor(); update_topline(); // scroll to show the line *************** *** 4282,4295 **** // Check if there is anything to display if (!qf_stack_empty(qi)) { ! char_u dirname[MAXPATHL]; *dirname = NUL; // Add one line for each error if (old_last == NULL) { ! qfp = qi->qf_lists[qi->qf_curlist].qf_start; lnum = 0; } else --- 4290,4304 ---- // Check if there is anything to display if (!qf_stack_empty(qi)) { ! qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; ! char_u dirname[MAXPATHL]; *dirname = NUL; // Add one line for each error if (old_last == NULL) { ! qfp = qfl->qf_start; lnum = 0; } else *************** *** 4297,4303 **** qfp = old_last->qf_next; lnum = buf->b_ml.ml_line_count; } ! while (lnum < qi->qf_lists[qi->qf_curlist].qf_count) { if (qf_buf_add_line(buf, lnum, qfp, dirname) == FAIL) break; --- 4306,4312 ---- qfp = old_last->qf_next; lnum = buf->b_ml.ml_line_count; } ! while (lnum < qfl->qf_count) { if (qf_buf_add_line(buf, lnum, qfp, dirname) == FAIL) break; *************** *** 4345,4353 **** * For every change made to the quickfix list, update the changed tick. */ static void ! qf_list_changed(qf_info_T *qi, int qf_idx) { ! qi->qf_lists[qf_idx].qf_changedtick++; } /* --- 4354,4362 ---- * For every change made to the quickfix list, update the changed tick. */ static void ! qf_list_changed(qf_list_T *qfl) { ! qfl->qf_changedtick++; } /* *************** *** 4595,4601 **** goto cleanup; } if (res >= 0) ! qf_list_changed(qi, qi->qf_curlist); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. --- 4604,4610 ---- goto cleanup; } if (res >= 0) ! qf_list_changed(&qi->qf_lists[qi->qf_curlist]); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. *************** *** 4620,4625 **** --- 4629,4635 ---- qf_get_size(exarg_T *eap) { qf_info_T *qi = &ql_info; + qf_list_T *qfl; qfline_T *qfp; int i, sz = 0; int prev_fnum = 0; *************** *** 4632,4639 **** return 0; } ! for (i = 0, qfp = qi->qf_lists[qi->qf_curlist].qf_start; ! i < qi->qf_lists[qi->qf_curlist].qf_count && qfp != NULL; ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) --- 4642,4649 ---- return 0; } ! qfl = &qi->qf_lists[qi->qf_curlist]; ! for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count && qfp != NULL; ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) *************** *** 4935,4941 **** return; } if (res >= 0) ! qf_list_changed(qi, qi->qf_curlist); save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; if (au_name != NULL) apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf); --- 4945,4951 ---- return; } if (res >= 0) ! qf_list_changed(&qi->qf_lists[qi->qf_curlist]); save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; if (au_name != NULL) apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf); *************** *** 5204,5209 **** --- 5214,5220 ---- char_u *p; int fi; qf_info_T *qi = &ql_info; + qf_list_T *qfl; int_u save_qfid; win_T *wp = NULL; buf_T *buf; *************** *** 5410,5419 **** FreeWild(fcount, fnames); ! qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; ! qi->qf_lists[qi->qf_curlist].qf_ptr = qi->qf_lists[qi->qf_curlist].qf_start; ! qi->qf_lists[qi->qf_curlist].qf_index = 1; ! qf_list_changed(qi, qi->qf_curlist); qf_update_buffer(qi, NULL); --- 5421,5431 ---- FreeWild(fcount, fnames); ! qfl = &qi->qf_lists[qi->qf_curlist]; ! qfl->qf_nonevalid = FALSE; ! qfl->qf_ptr = qfl->qf_start; ! qfl->qf_index = 1; ! qf_list_changed(qfl); qf_update_buffer(qi, NULL); *************** *** 5915,5921 **** status = dict_add_number(retdict, "size", 0); if ((status == OK) && (flags & QF_GETLIST_TICK)) status = dict_add_number(retdict, "changedtick", 0); ! if ((status == OK) && (qi != &ql_info) && (flags & QF_GETLIST_FILEWINID)) status = dict_add_number(retdict, "filewinid", 0); return status; --- 5927,5933 ---- status = dict_add_number(retdict, "size", 0); if ((status == OK) && (flags & QF_GETLIST_TICK)) status = dict_add_number(retdict, "changedtick", 0); ! if ((status == OK) && IS_LL_STACK(qi) && (flags & QF_GETLIST_FILEWINID)) status = dict_add_number(retdict, "filewinid", 0); return status; *************** *** 5925,5933 **** * Return the quickfix list title as 'title' in retdict */ static int ! qf_getprop_title(qf_info_T *qi, int qf_idx, dict_T *retdict) { ! return dict_add_string(retdict, "title", qi->qf_lists[qf_idx].qf_title); } /* --- 5937,5945 ---- * Return the quickfix list title as 'title' in retdict */ static int ! qf_getprop_title(qf_list_T *qfl, dict_T *retdict) { ! return dict_add_string(retdict, "title", qfl->qf_title); } /* *************** *** 5973,5989 **** * Return the quickfix list context (if any) as 'context' in retdict. */ static int ! qf_getprop_ctx(qf_info_T *qi, int qf_idx, dict_T *retdict) { int status; dictitem_T *di; ! if (qi->qf_lists[qf_idx].qf_ctx != NULL) { di = dictitem_alloc((char_u *)"context"); if (di != NULL) { ! copy_tv(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv); status = dict_add(retdict, di); if (status == FAIL) dictitem_free(di); --- 5985,6001 ---- * Return the quickfix list context (if any) as 'context' in retdict. */ static int ! qf_getprop_ctx(qf_list_T *qfl, dict_T *retdict) { int status; dictitem_T *di; ! if (qfl->qf_ctx != NULL) { di = dictitem_alloc((char_u *)"context"); if (di != NULL) { ! copy_tv(qfl->qf_ctx, &di->di_tv); status = dict_add(retdict, di); if (status == FAIL) dictitem_free(di); *************** *** 5998,6013 **** } /* ! * Return the quickfix list index as 'idx' in retdict */ static int qf_getprop_idx(qf_info_T *qi, int qf_idx, dict_T *retdict) { ! int idx = qi->qf_lists[qf_idx].qf_index; if (qf_list_empty(qi, qf_idx)) ! // For empty lists, qf_index is set to 1 ! idx = 0; ! return dict_add_number(retdict, "idx", idx); } /* --- 6010,6025 ---- } /* ! * Return the current quickfix list index as 'idx' in retdict */ static int qf_getprop_idx(qf_info_T *qi, int qf_idx, dict_T *retdict) { ! int curidx = qi->qf_lists[qf_idx].qf_index; if (qf_list_empty(qi, qf_idx)) ! // For empty lists, current index is set to 0 ! curidx = 0; ! return dict_add_number(retdict, "idx", curidx); } /* *************** *** 6021,6027 **** qf_info_T *qi = &ql_info; qf_list_T *qfl; int status = OK; ! int qf_idx; dictitem_T *di; int flags = QF_GETLIST_NONE; --- 6033,6039 ---- qf_info_T *qi = &ql_info; qf_list_T *qfl; int status = OK; ! int qf_idx = INVALID_QFIDX; dictitem_T *di; int flags = QF_GETLIST_NONE; *************** *** 6043,6049 **** qfl = &qi->qf_lists[qf_idx]; if (flags & QF_GETLIST_TITLE) ! status = qf_getprop_title(qi, qf_idx, retdict); if ((status == OK) && (flags & QF_GETLIST_NR)) status = dict_add_number(retdict, "nr", qf_idx + 1); if ((status == OK) && (flags & QF_GETLIST_WINID)) --- 6055,6061 ---- qfl = &qi->qf_lists[qf_idx]; if (flags & QF_GETLIST_TITLE) ! status = qf_getprop_title(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_NR)) status = dict_add_number(retdict, "nr", qf_idx + 1); if ((status == OK) && (flags & QF_GETLIST_WINID)) *************** *** 6051,6057 **** if ((status == OK) && (flags & QF_GETLIST_ITEMS)) status = qf_getprop_items(qi, qf_idx, retdict); if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) ! status = qf_getprop_ctx(qi, qf_idx, retdict); if ((status == OK) && (flags & QF_GETLIST_ID)) status = dict_add_number(retdict, "id", qfl->qf_id); if ((status == OK) && (flags & QF_GETLIST_IDX)) --- 6063,6069 ---- if ((status == OK) && (flags & QF_GETLIST_ITEMS)) status = qf_getprop_items(qi, qf_idx, retdict); if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) ! status = qf_getprop_ctx(qfl, retdict); if ((status == OK) && (flags & QF_GETLIST_ID)) status = dict_add_number(retdict, "id", qfl->qf_id); if ((status == OK) && (flags & QF_GETLIST_IDX)) *************** *** 6277,6288 **** static int qf_setprop_title(qf_info_T *qi, int qf_idx, dict_T *what, dictitem_T *di) { if (di->di_tv.v_type != VAR_STRING) return FAIL; ! vim_free(qi->qf_lists[qf_idx].qf_title); ! qi->qf_lists[qf_idx].qf_title = ! get_dict_string(what, (char_u *)"title", TRUE); if (qf_idx == qi->qf_curlist) qf_update_win_titlevar(qi); --- 6289,6301 ---- static int qf_setprop_title(qf_info_T *qi, int qf_idx, dict_T *what, dictitem_T *di) { + qf_list_T *qfl = &qi->qf_lists[qf_idx]; + if (di->di_tv.v_type != VAR_STRING) return FAIL; ! vim_free(qfl->qf_title); ! qfl->qf_title = get_dict_string(what, (char_u *)"title", TRUE); if (qf_idx == qi->qf_curlist) qf_update_win_titlevar(qi); *************** *** 6375,6380 **** --- 6388,6394 ---- int retval = FAIL; int qf_idx; int newlist = FALSE; + qf_list_T *qfl; if (action == ' ' || qf_stack_empty(qi)) newlist = TRUE; *************** *** 6390,6395 **** --- 6404,6410 ---- qf_idx = qi->qf_curlist; } + qfl = &qi->qf_lists[qf_idx]; if ((di = dict_find(what, (char_u *)"title", -1)) != NULL) retval = qf_setprop_title(qi, qf_idx, what, di); if ((di = dict_find(what, (char_u *)"items", -1)) != NULL) *************** *** 6397,6413 **** if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) retval = qf_setprop_items_from_lines(qi, qf_idx, what, di, action); if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) ! retval = qf_setprop_context(&qi->qf_lists[qf_idx], di); if (retval == OK) ! qf_list_changed(qi, qf_idx); return retval; } /* ! * Find the non-location list window with the specified location list in the ! * current tabpage. */ static win_T * find_win_with_ll(qf_info_T *qi) --- 6412,6428 ---- if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) retval = qf_setprop_items_from_lines(qi, qf_idx, what, di, action); if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) ! retval = qf_setprop_context(qfl, di); if (retval == OK) ! qf_list_changed(qfl); return retval; } /* ! * Find the non-location list window with the specified location list stack in ! * the current tabpage. */ static win_T * find_win_with_ll(qf_info_T *qi) *************** *** 6508,6514 **** { retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); if (retval == OK) ! qf_list_changed(qi, qi->qf_curlist); } return retval; --- 6523,6529 ---- { retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); if (retval == OK) ! qf_list_changed(&qi->qf_lists[qi->qf_curlist]); } return retval; *************** *** 6654,6660 **** eap->line1, eap->line2, qf_title, NULL); if (res >= 0) ! qf_list_changed(qi, qi->qf_curlist); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. --- 6669,6675 ---- eap->line1, eap->line2, qf_title, NULL); if (res >= 0) ! qf_list_changed(&qi->qf_lists[qi->qf_curlist]); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. *************** *** 6737,6743 **** (linenr_T)0, (linenr_T)0, qf_cmdtitle(*eap->cmdlinep), NULL); if (res >= 0) ! qf_list_changed(qi, qi->qf_curlist); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. --- 6752,6758 ---- (linenr_T)0, (linenr_T)0, qf_cmdtitle(*eap->cmdlinep), NULL); if (res >= 0) ! qf_list_changed(&qi->qf_lists[qi->qf_curlist]); // Remember the current quickfix list identifier, so that we can // check for autocommands changing the current quickfix list. *************** *** 7013,7018 **** --- 7028,7035 ---- regmatch.rm_ic = FALSE; if (regmatch.regprog != NULL) { + qf_list_T *qfl; + // create a new quickfix list qf_new_list(qi, qf_cmdtitle(*eap->cmdlinep)); *************** *** 7020,7029 **** vim_regfree(regmatch.regprog); ! qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; ! qi->qf_lists[qi->qf_curlist].qf_ptr = ! qi->qf_lists[qi->qf_curlist].qf_start; ! qi->qf_lists[qi->qf_curlist].qf_index = 1; } if (p_cpo == empty_option) --- 7037,7048 ---- vim_regfree(regmatch.regprog); ! qfl = &qi->qf_lists[qi->qf_curlist]; ! qfl->qf_nonevalid = FALSE; ! qfl->qf_ptr = qfl->qf_start; ! qfl->qf_index = 1; ! qf_list_changed(qfl); ! qf_update_buffer(qi, NULL); } if (p_cpo == empty_option) *************** *** 7032,7040 **** // Darn, some plugin changed the value. free_string_option(save_cpo); - qf_list_changed(qi, qi->qf_curlist); - qf_update_buffer(qi, NULL); - if (au_name != NULL) { apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, --- 7051,7056 ---- *** ../vim-8.1.0468/src/testdir/test_quickfix.vim 2018-09-02 15:18:38.910627833 +0200 --- src/testdir/test_quickfix.vim 2018-10-11 17:37:31.930172891 +0200 *************** *** 558,563 **** --- 558,565 ---- " Search for non existing help string call assert_fails('Xhelpgrep a1b2c3', 'E480:') + " Invalid regular expression + call assert_fails('Xhelpgrep \@