To: vim_dev@googlegroups.com Subject: Patch 8.0.1752 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1752 Problem: qf_set_properties() is to long. Solution: Refactor the function. Define INVALID_QFIDX. (Yegappan Lakshmanan, closes #2812) Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.0.1751/src/quickfix.c 2018-04-23 21:29:42.157966083 +0200 --- src/quickfix.c 2018-04-24 13:46:00.592482295 +0200 *************** *** 46,51 **** --- 46,52 ---- * There is a stack of error lists. */ #define LISTCOUNT 10 + #define INVALID_QFIDX (-1) /* * Quickfix/Location list definition *************** *** 5085,5091 **** { qf_idx = di->di_tv.vval.v_number - 1; if (qf_idx < 0 || qf_idx >= qi->qf_listcount) ! qf_idx = -1; } } else if (di->di_tv.v_type == VAR_STRING --- 5086,5092 ---- { qf_idx = di->di_tv.vval.v_number - 1; if (qf_idx < 0 || qf_idx >= qi->qf_listcount) ! qf_idx = INVALID_QFIDX; } } else if (di->di_tv.v_type == VAR_STRING *************** *** 5094,5100 **** /* Get the last quickfix list number */ qf_idx = qi->qf_listcount - 1; else ! qf_idx = -1; } if ((di = dict_find(what, (char_u *)"id", -1)) != NULL) --- 5095,5101 ---- /* Get the last quickfix list number */ qf_idx = qi->qf_listcount - 1; else ! qf_idx = INVALID_QFIDX; } if ((di = dict_find(what, (char_u *)"id", -1)) != NULL) *************** *** 5109,5115 **** qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); } else ! qf_idx = -1; } return qf_idx; --- 5110,5116 ---- qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); } else ! qf_idx = INVALID_QFIDX; } return qf_idx; *************** *** 5251,5257 **** qf_idx = qf_getprop_qfidx(qi, what); /* List is not present or is empty */ ! if (qi == NULL || qi->qf_listcount == 0 || qf_idx == -1) return qf_getprop_defaults(qi, flags, retdict); if (flags & QF_GETLIST_TITLE) --- 5252,5258 ---- qf_idx = qf_getprop_qfidx(qi, what); /* List is not present or is empty */ ! if (qi == NULL || qi->qf_listcount == 0 || qf_idx == INVALID_QFIDX) return qf_getprop_defaults(qi, flags, retdict); if (flags & QF_GETLIST_TITLE) *************** *** 5405,5423 **** return retval; } static int ! qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) { dictitem_T *di; ! int retval = FAIL; ! int qf_idx; ! int newlist = FALSE; ! char_u *errorformat = p_efm; - if (action == ' ' || qi->qf_curlist == qi->qf_listcount) - newlist = TRUE; - - qf_idx = qi->qf_curlist; /* default is the current list */ if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) { /* Use the specified quickfix/location list */ --- 5406,5424 ---- return retval; } + /* + * Get the quickfix list index from 'nr' or 'id' + */ static int ! qf_setprop_get_qfidx( ! qf_info_T *qi, ! dict_T *what, ! int action, ! int *newlist) { dictitem_T *di; ! int qf_idx = qi->qf_curlist; /* default is the current list */ if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) { /* Use the specified quickfix/location list */ *************** *** 5434,5551 **** * non-available list and add the new list at the end of the * stack. */ ! newlist = TRUE; ! qf_idx = qi->qf_listcount - 1; } else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) ! return FAIL; else if (action != ' ') ! newlist = FALSE; /* use the specified list */ } else if (di->di_tv.v_type == VAR_STRING ! && di->di_tv.vval.v_string != NULL ! && STRCMP(di->di_tv.vval.v_string, "$") == 0) { if (qi->qf_listcount > 0) qf_idx = qi->qf_listcount - 1; ! else if (newlist) qf_idx = 0; else ! return FAIL; } else ! return FAIL; } ! if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL) { /* Use the quickfix/location list with the specified id */ ! if (di->di_tv.v_type == VAR_NUMBER) ! { ! qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); ! if (qf_idx == -1) ! return FAIL; /* List not found */ ! } ! else ! return FAIL; ! } ! if (newlist) ! { ! qi->qf_curlist = qf_idx; ! qf_new_list(qi, title); ! qf_idx = qi->qf_curlist; } ! if ((di = dict_find(what, (char_u *)"title", -1)) != NULL) ! { ! if (di->di_tv.v_type == VAR_STRING) ! { ! 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); ! retval = OK; ! } ! } ! if ((di = dict_find(what, (char_u *)"items", -1)) != NULL) ! { ! if (di->di_tv.v_type == VAR_LIST) ! { ! char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title); ! retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list, ! title_save, action == ' ' ? 'a' : action); ! if (action == 'r') ! { ! /* ! * When replacing the quickfix list entries using ! * qf_add_entries(), the title is set with a ':' prefix. ! * Restore the title with the saved title. ! */ ! vim_free(qi->qf_lists[qf_idx].qf_title); ! qi->qf_lists[qf_idx].qf_title = vim_strsave(title_save); ! } ! vim_free(title_save); ! } ! } ! if ((di = dict_find(what, (char_u *)"efm", -1)) != NULL) { ! if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL) ! return FAIL; ! errorformat = di->di_tv.vval.v_string; } ! if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) { ! /* Only a List value is supported */ ! if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) ! { ! if (action == 'r') ! qf_free_items(qi, qf_idx); ! if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat, ! FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) ! retval = OK; ! } ! else return FAIL; } ! if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) ! { ! typval_T *ctx; ! free_tv(qi->qf_lists[qf_idx].qf_ctx); ! ctx = alloc_tv(); ! if (ctx != NULL) ! copy_tv(&di->di_tv, ctx); ! qi->qf_lists[qf_idx].qf_ctx = ctx; retval = OK; } if (retval == OK) qf_list_changed(qi, qf_idx); --- 5435,5613 ---- * non-available list and add the new list at the end of the * stack. */ ! *newlist = TRUE; ! qf_idx = qi->qf_listcount > 0 ? qi->qf_listcount - 1 : 0; } else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) ! return INVALID_QFIDX; else if (action != ' ') ! *newlist = FALSE; /* use the specified list */ } else if (di->di_tv.v_type == VAR_STRING ! && di->di_tv.vval.v_string != NULL ! && STRCMP(di->di_tv.vval.v_string, "$") == 0) { if (qi->qf_listcount > 0) qf_idx = qi->qf_listcount - 1; ! else if (*newlist) qf_idx = 0; else ! return INVALID_QFIDX; } else ! return INVALID_QFIDX; } ! if (!*newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL) { /* Use the quickfix/location list with the specified id */ ! if (di->di_tv.v_type != VAR_NUMBER) ! return INVALID_QFIDX; ! return qf_id2nr(qi, di->di_tv.vval.v_number); } ! return qf_idx; ! } ! /* ! * Set the quickfix list title. ! */ ! 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); ! ! return OK; ! } ! /* ! * Set quickfix list items/entries. ! */ ! static int ! qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action) ! { ! int retval = FAIL; ! char_u *title_save; ! ! if (di->di_tv.v_type != VAR_LIST) ! return FAIL; ! ! title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title); ! retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list, ! title_save, action == ' ' ? 'a' : action); ! if (action == 'r') { ! /* ! * When replacing the quickfix list entries using ! * qf_add_entries(), the title is set with a ':' prefix. ! * Restore the title with the saved title. ! */ ! vim_free(qi->qf_lists[qf_idx].qf_title); ! qi->qf_lists[qf_idx].qf_title = vim_strsave(title_save); } + vim_free(title_save); ! return retval; ! } ! ! /* ! * Set quickfix list items/entries from a list of lines. ! */ ! static int ! qf_setprop_items_from_lines( ! qf_info_T *qi, ! int qf_idx, ! dict_T *what, ! dictitem_T *di, ! int action) ! { ! char_u *errorformat = p_efm; ! dictitem_T *efm_di; ! int retval = FAIL; ! ! /* Use the user supplied errorformat settings (if present) */ ! if ((efm_di = dict_find(what, (char_u *)"efm", -1)) != NULL) { ! if (efm_di->di_tv.v_type != VAR_STRING || ! efm_di->di_tv.vval.v_string == NULL) return FAIL; + errorformat = efm_di->di_tv.vval.v_string; } ! /* Only a List value is supported */ ! if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) ! return FAIL; ! if (action == 'r') ! qf_free_items(qi, qf_idx); ! if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat, ! FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) retval = OK; + + return retval; + } + + /* + * Set quickfix list context. + */ + static int + qf_setprop_context(qf_info_T *qi, int qf_idx, dictitem_T *di) + { + typval_T *ctx; + + free_tv(qi->qf_lists[qf_idx].qf_ctx); + ctx = alloc_tv(); + if (ctx != NULL) + copy_tv(&di->di_tv, ctx); + qi->qf_lists[qf_idx].qf_ctx = ctx; + + return OK; + } + + /* + * Set quickfix/location list properties (title, items, context). + * Also used to add items from parsing a list of lines. + * Used by the setqflist() and setloclist() VimL functions. + */ + static int + qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) + { + dictitem_T *di; + int retval = FAIL; + int qf_idx; + int newlist = FALSE; + + if (action == ' ' || qi->qf_curlist == qi->qf_listcount) + newlist = TRUE; + + qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist); + if (qf_idx == INVALID_QFIDX) /* List not found */ + return FAIL; + + if (newlist) + { + qi->qf_curlist = qf_idx; + qf_new_list(qi, title); + qf_idx = qi->qf_curlist; } + 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) + retval = qf_setprop_items(qi, qf_idx, di, action); + 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_idx, di); + if (retval == OK) qf_list_changed(qi, qf_idx); *** ../vim-8.0.1751/src/testdir/test_quickfix.vim 2018-04-23 21:29:42.157966083 +0200 --- src/testdir/test_quickfix.vim 2018-04-24 13:46:22.596357975 +0200 *************** *** 1795,1800 **** --- 1795,1803 ---- call assert_equal(0, s) let d = g:Xgetlist({"title":1}) call assert_equal('Sample', d.title) + " Try setting title to a non-string value + call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']})) + call assert_equal('Sample', g:Xgetlist({"title":1}).title) Xopen call assert_equal('Sample', w:quickfix_title) *************** *** 1943,1948 **** --- 1946,1954 ---- call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]}) call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum) + " Try setting the items using a string + call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'})) + " Save and restore the quickfix stack call g:Xsetlist([], 'f') call assert_equal(0, g:Xgetlist({'nr':'$'}).nr) *** ../vim-8.0.1751/src/version.c 2018-04-24 13:29:47.717890672 +0200 --- src/version.c 2018-04-24 13:47:29.559979394 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1752, /**/ -- hundred-and-one symptoms of being an internet addict: 265. Your reason for not staying in touch with family is that they do not have e-mail addresses. /// 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 ///