From 1cfe83c2a2d5d1d5dcc37bdcdb9dba4107e41de7 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 5 Mar 2023 14:47:51 +0800 Subject: vim-patch:9.0.0736: quickfix listing does not handle very long messages Problem: Quickfix listing does not handle very long messages. Solution: Use a growarray instead of a fixed size buffer. (Yegappan Lakshmanan, closes vim/vim#11357) https://github.com/vim/vim/commit/f8412c9d7cc487dacf47a217ae947da68a525c53 Override Test_very_long_error_line() with a rewrite that doesn't use deferred delete and string interpolation. Co-authored-by: Yegappan Lakshmanan --- src/nvim/quickfix.c | 147 +++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 77 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 5518fdfa51..af2d10798a 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2807,13 +2807,15 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf update_screen(); } } - snprintf(IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index, - qf_get_curlist(qi)->qf_count, - qf_ptr->qf_cleared ? _(" (line deleted)") : "", - qf_types(qf_ptr->qf_type, qf_ptr->qf_nr)); + vim_snprintf(IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index, + qf_get_curlist(qi)->qf_count, + qf_ptr->qf_cleared ? _(" (line deleted)") : "", + qf_types(qf_ptr->qf_type, qf_ptr->qf_nr)); // Add the message, skipping leading whitespace and newlines. - int len = (int)strlen(IObuff); - qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len); + garray_T ga; + ga_init(&ga, 1, 256); + ga_concat(&ga, IObuff); + qf_fmt_text(&ga, skipwhite(qf_ptr->qf_text)); // Output the message. Overwrite to avoid scrolling when the 'O' // flag is present in 'shortmess'; But when not jumping, print the @@ -2825,8 +2827,9 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf msg_scroll = false; } msg_ext_set_kind("quickfix"); - msg_attr_keep(IObuff, 0, true, false); + msg_attr_keep(ga.ga_data, 0, true, false); msg_scroll = (int)i; + ga_clear(&ga); } /// Find a usable window for opening a file from the quickfix/location list. If @@ -3086,41 +3089,32 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) if (qfp->qf_lnum != 0) { msg_puts_attr(":", qfSepAttr); } + garray_T ga; + ga_init(&ga, 1, 256); if (qfp->qf_lnum == 0) { - IObuff[0] = NUL; + ga_append(&ga, NUL); } else { - qf_range_text(qfp, IObuff, IOSIZE); + qf_range_text(&ga, qfp); } - vim_snprintf(IObuff + strlen(IObuff), IOSIZE, "%s", qf_types(qfp->qf_type, qfp->qf_nr)); - msg_puts_attr((const char *)IObuff, qfLineAttr); + ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); + ga_append(&ga, NUL); + msg_puts_attr(ga.ga_data, qfLineAttr); + ga_clear(&ga); msg_puts_attr(":", qfSepAttr); if (qfp->qf_pattern != NULL) { - qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE); - msg_puts((const char *)IObuff); + qf_fmt_text(&ga, qfp->qf_pattern); + msg_puts(ga.ga_data); + ga_clear(&ga); msg_puts_attr(":", qfSepAttr); } msg_puts(" "); - char *tbuf = IObuff; - size_t tbuflen = IOSIZE; - size_t len = strlen(qfp->qf_text) + 3; - - if (len > IOSIZE) { - tbuf = xmalloc(len); - tbuflen = len; - } - // Remove newlines and leading whitespace from the text. For an // unrecognized line keep the indent, the compiler may mark a word // with ^^^^. - qf_fmt_text((fname != NULL || qfp->qf_lnum != 0) - ? skipwhite(qfp->qf_text) : qfp->qf_text, - tbuf, (int)tbuflen); - msg_prt_line(tbuf, false); - - if (tbuf != IObuff) { - xfree(tbuf); - } + qf_fmt_text(&ga, (fname != NULL || qfp->qf_lnum != 0) ? skipwhite(qfp->qf_text) : qfp->qf_text); + msg_prt_line(ga.ga_data, false); + ga_clear(&ga); } // ":clist": list all errors @@ -3197,49 +3191,54 @@ void qf_list(exarg_T *eap) } } -// Remove newlines and leading whitespace from an error message. -// Put the result in "buf[bufsize]". -static void qf_fmt_text(const char *restrict text, char *restrict buf, int bufsize) +/// Remove newlines and leading whitespace from an error message. +/// Add the result to the grow array "gap". +static void qf_fmt_text(garray_T *gap, const char *restrict text) FUNC_ATTR_NONNULL_ALL { - int i; const char *p = (char *)text; - for (i = 0; *p != NUL && i < bufsize - 1; i++) { + while (*p != NUL) { if (*p == '\n') { - buf[i] = ' '; + ga_append(gap, ' '); while (*++p != NUL) { if (!ascii_iswhite(*p) && *p != '\n') { break; } } } else { - buf[i] = *p++; + ga_append(gap, (uint8_t)(*p++)); } } - buf[i] = NUL; + + ga_append(gap, NUL); } -// Range information from lnum, col, end_lnum, and end_col. -// Put the result in "buf[bufsize]". -static void qf_range_text(const qfline_T *qfp, char *buf, int bufsize) +/// Add the range information from the lnum, col, end_lnum, and end_col values +/// of a quickfix entry to the grow array "gap". +static void qf_range_text(garray_T *gap, const qfline_T *qfp) { - vim_snprintf(buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum); - int len = (int)strlen(buf); + char *const buf = IObuff; + const size_t bufsize = IOSIZE; + + vim_snprintf(buf, bufsize, "%" PRIdLINENR, qfp->qf_lnum); + size_t len = strlen(buf); if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum) { - vim_snprintf(buf + len, (size_t)(bufsize - len), "-%" PRIdLINENR, qfp->qf_end_lnum); - len += (int)strlen(buf + len); + vim_snprintf(buf + len, bufsize - len, "-%" PRIdLINENR, qfp->qf_end_lnum); + len += strlen(buf + len); } if (qfp->qf_col > 0) { - vim_snprintf(buf + len, (size_t)(bufsize - len), " col %d", qfp->qf_col); - len += (int)strlen(buf + len); + vim_snprintf(buf + len, bufsize - len, " col %d", qfp->qf_col); + len += strlen(buf + len); if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col) { - vim_snprintf(buf + len, (size_t)(bufsize - len), "-%d", qfp->qf_end_col); - len += (int)strlen(buf + len); + vim_snprintf(buf + len, bufsize - len, "-%d", qfp->qf_end_col); + len += strlen(buf + len); } } buf[len] = NUL; + + ga_concat_len(gap, buf, len); } /// Display information (list number, list size and the title) about a @@ -3945,21 +3944,22 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli char *dirname, char *qftf_str, bool first_bufline) FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5) { + garray_T ga; + ga_init(&ga, 1, 256); + // If the 'quickfixtextfunc' function returned a non-empty custom string // for this entry, then use it. if (qftf_str != NULL && *qftf_str != NUL) { - xstrlcpy(IObuff, qftf_str, IOSIZE); + ga_concat(&ga, qftf_str); } else { buf_T *errbuf; - int len; if (qfp->qf_module != NULL) { - xstrlcpy(IObuff, qfp->qf_module, IOSIZE); - len = (int)strlen(IObuff); + ga_concat(&ga, qfp->qf_module); } else if (qfp->qf_fnum != 0 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL && errbuf->b_fname != NULL) { if (qfp->qf_type == 1) { // :helpgrep - xstrlcpy(IObuff, path_tail(errbuf->b_fname), IOSIZE); + ga_concat(&ga, path_tail(errbuf->b_fname)); } else { // Shorten the file name if not done already. // For optimization, do this only for the first entry in a @@ -3972,42 +3972,35 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli } shorten_buf_fname(errbuf, dirname, false); } - xstrlcpy(IObuff, errbuf->b_fname, IOSIZE); + ga_concat(&ga, errbuf->b_fname); } - len = (int)strlen(IObuff); - } else { - len = 0; - } - if (len < IOSIZE - 1) { - IObuff[len++] = '|'; } - if (qfp->qf_lnum > 0) { - qf_range_text(qfp, IObuff + len, IOSIZE - len); - len += (int)strlen(IObuff + len); - snprintf(IObuff + len, (size_t)(IOSIZE - len), "%s", qf_types(qfp->qf_type, - qfp->qf_nr)); - len += (int)strlen(IObuff + len); + ga_append(&ga, '|'); + + if (qfp->qf_lnum > 0) { + qf_range_text(&ga, qfp); + ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); } else if (qfp->qf_pattern != NULL) { - qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); - len += (int)strlen(IObuff + len); - } - if (len < IOSIZE - 2) { - IObuff[len++] = '|'; - IObuff[len++] = ' '; + qf_fmt_text(&ga, qfp->qf_pattern); } + ga_append(&ga, '|'); + ga_append(&ga, ' '); // Remove newlines and leading whitespace from the text. // For an unrecognized line keep the indent, the compiler may // mark a word with ^^^^. - qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, - IObuff + len, IOSIZE - len); + qf_fmt_text(&ga, ga.ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); } - if (ml_append_buf(buf, lnum, IObuff, - (colnr_T)strlen(IObuff) + 1, false) == FAIL) { + ga_append(&ga, NUL); + + if (ml_append_buf(buf, lnum, ga.ga_data, ga.ga_len + 1, false) == FAIL) { return FAIL; } + + ga_clear(&ga); + return OK; } -- cgit From 1adad44b7ce6574f505f4cf5df3c8e21c0747f93 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 5 Mar 2023 16:52:47 +0800 Subject: vim-patch:9.0.0749: alloc/free of buffer for each quickfix entry is inefficient Problem: Alloc/free of buffer for each quickfix entry is inefficient. Solution: Use a shared grow array. (Yegappan Lakshmanan, closes vim/vim#11365) https://github.com/vim/vim/commit/975a665d4811649a51e2c6a97a6ce096290d87ae Co-authored-by: Yegappan Lakshmanan --- src/nvim/quickfix.c | 107 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 41 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index af2d10798a..51cc7fa30b 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -245,6 +245,10 @@ typedef struct vgr_args_S { #endif static char *e_no_more_items = N_("E553: No more items"); +static char *e_current_quickfix_list_was_changed = + N_("E925: Current quickfix list was changed"); +static char *e_current_location_list_was_changed = + N_("E926: Current location list was changed"); // Quickfix window check helper macro #define IS_QF_WINDOW(wp) (bt_quickfix((wp)->w_buffer) && (wp)->w_llist_ref == NULL) @@ -275,10 +279,24 @@ static char *e_no_more_items = N_("E553: No more items"); static char *qf_last_bufname = NULL; static bufref_T qf_last_bufref = { NULL, 0, 0 }; -static char *e_current_quickfix_list_was_changed = - N_("E925: Current quickfix list was changed"); -static char *e_current_location_list_was_changed = - N_("E926: Current location list was changed"); +static garray_T qfga; + +/// Get a growarray to buffer text in. Shared between various commands to avoid +/// many alloc/free calls. +static garray_T *qfga_get(void) +{ + static bool initialized = false; + + if (!initialized) { + initialized = true; + ga_init(&qfga, 1, 256); + } + + // Retain ga_data from previous use. Reset the length to zero. + qfga.ga_len = 0; + + return &qfga; +} // Counter to prevent autocmds from freeing up location lists when they are // still being used. @@ -2799,6 +2817,8 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf_T *old_curbuf, linenr_T old_lnum) { + garray_T *const gap = qfga_get(); + // Update the screen before showing the message, unless the screen // scrolled up. if (!msg_scrolled) { @@ -2812,10 +2832,8 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf qf_ptr->qf_cleared ? _(" (line deleted)") : "", qf_types(qf_ptr->qf_type, qf_ptr->qf_nr)); // Add the message, skipping leading whitespace and newlines. - garray_T ga; - ga_init(&ga, 1, 256); - ga_concat(&ga, IObuff); - qf_fmt_text(&ga, skipwhite(qf_ptr->qf_text)); + ga_concat(gap, IObuff); + qf_fmt_text(gap, skipwhite(qf_ptr->qf_text)); // Output the message. Overwrite to avoid scrolling when the 'O' // flag is present in 'shortmess'; But when not jumping, print the @@ -2827,9 +2845,8 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf msg_scroll = false; } msg_ext_set_kind("quickfix"); - msg_attr_keep(ga.ga_data, 0, true, false); + msg_attr_keep(gap->ga_data, 0, true, false); msg_scroll = (int)i; - ga_clear(&ga); } /// Find a usable window for opening a file from the quickfix/location list. If @@ -3089,22 +3106,20 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) if (qfp->qf_lnum != 0) { msg_puts_attr(":", qfSepAttr); } - garray_T ga; - ga_init(&ga, 1, 256); + garray_T *gap = qfga_get(); if (qfp->qf_lnum == 0) { - ga_append(&ga, NUL); + ga_append(gap, NUL); } else { - qf_range_text(&ga, qfp); + qf_range_text(gap, qfp); } - ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); - ga_append(&ga, NUL); - msg_puts_attr(ga.ga_data, qfLineAttr); - ga_clear(&ga); + ga_concat(gap, qf_types(qfp->qf_type, qfp->qf_nr)); + ga_append(gap, NUL); + msg_puts_attr(gap->ga_data, qfLineAttr); msg_puts_attr(":", qfSepAttr); if (qfp->qf_pattern != NULL) { - qf_fmt_text(&ga, qfp->qf_pattern); - msg_puts(ga.ga_data); - ga_clear(&ga); + gap = qfga_get(); + qf_fmt_text(gap, qfp->qf_pattern); + msg_puts(gap->ga_data); msg_puts_attr(":", qfSepAttr); } msg_puts(" "); @@ -3112,9 +3127,9 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) // Remove newlines and leading whitespace from the text. For an // unrecognized line keep the indent, the compiler may mark a word // with ^^^^. - qf_fmt_text(&ga, (fname != NULL || qfp->qf_lnum != 0) ? skipwhite(qfp->qf_text) : qfp->qf_text); - msg_prt_line(ga.ga_data, false); - ga_clear(&ga); + gap = qfga_get(); + qf_fmt_text(gap, (fname != NULL || qfp->qf_lnum != 0) ? skipwhite(qfp->qf_text) : qfp->qf_text); + msg_prt_line(gap->ga_data, false); } // ":clist": list all errors @@ -3944,22 +3959,21 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli char *dirname, char *qftf_str, bool first_bufline) FUNC_ATTR_NONNULL_ARG(1, 2, 4, 5) { - garray_T ga; - ga_init(&ga, 1, 256); + garray_T *gap = qfga_get(); // If the 'quickfixtextfunc' function returned a non-empty custom string // for this entry, then use it. if (qftf_str != NULL && *qftf_str != NUL) { - ga_concat(&ga, qftf_str); + ga_concat(gap, qftf_str); } else { buf_T *errbuf; if (qfp->qf_module != NULL) { - ga_concat(&ga, qfp->qf_module); + ga_concat(gap, qfp->qf_module); } else if (qfp->qf_fnum != 0 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL && errbuf->b_fname != NULL) { if (qfp->qf_type == 1) { // :helpgrep - ga_concat(&ga, path_tail(errbuf->b_fname)); + ga_concat(gap, path_tail(errbuf->b_fname)); } else { // Shorten the file name if not done already. // For optimization, do this only for the first entry in a @@ -3972,35 +3986,33 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli } shorten_buf_fname(errbuf, dirname, false); } - ga_concat(&ga, errbuf->b_fname); + ga_concat(gap, errbuf->b_fname); } } - ga_append(&ga, '|'); + ga_append(gap, '|'); if (qfp->qf_lnum > 0) { - qf_range_text(&ga, qfp); - ga_concat(&ga, qf_types(qfp->qf_type, qfp->qf_nr)); + qf_range_text(gap, qfp); + ga_concat(gap, qf_types(qfp->qf_type, qfp->qf_nr)); } else if (qfp->qf_pattern != NULL) { - qf_fmt_text(&ga, qfp->qf_pattern); + qf_fmt_text(gap, qfp->qf_pattern); } - ga_append(&ga, '|'); - ga_append(&ga, ' '); + ga_append(gap, '|'); + ga_append(gap, ' '); // Remove newlines and leading whitespace from the text. // For an unrecognized line keep the indent, the compiler may // mark a word with ^^^^. - qf_fmt_text(&ga, ga.ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); + qf_fmt_text(gap, gap->ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); } - ga_append(&ga, NUL); + ga_append(gap, NUL); - if (ml_append_buf(buf, lnum, ga.ga_data, ga.ga_len + 1, false) == FAIL) { + if (ml_append_buf(buf, lnum, gap->ga_data, gap->ga_len + 1, false) == FAIL) { return FAIL; } - ga_clear(&ga); - return OK; } @@ -7207,6 +7219,19 @@ void ex_helpgrep(exarg_T *eap) } } +#if defined(EXITFREE) +void free_quickfix(void) +{ + qf_free_all(NULL); + // Free all location lists + FOR_ALL_TAB_WINDOWS(tab, win) { + qf_free_all(win); + } + + ga_clear(&qfga); +} +#endif + static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *rettv) { if (what_arg->v_type == VAR_UNKNOWN) { -- cgit From 749fe2c383f662bb13f97336329a0e08200c0a3b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 5 Mar 2023 17:03:00 +0800 Subject: vim-patch:9.0.0770: quickfix commands may keep memory allocated Problem: Quickfix commands may keep memory allocated. Solution: Free memory when it's a bit much. (Yegappan Lakshmanan, closes vim/vim#11379) https://github.com/vim/vim/commit/d8cd6f7427bc89aa38f42cc44f58bf5fb5f0f972 Co-authored-by: Yegappan Lakshmanan --- src/nvim/quickfix.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 51cc7fa30b..3c20c5239c 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -292,12 +292,26 @@ static garray_T *qfga_get(void) ga_init(&qfga, 1, 256); } - // Retain ga_data from previous use. Reset the length to zero. + // Reset the length to zero. Retain ga_data from previous use to avoid + // many alloc/free calls. qfga.ga_len = 0; return &qfga; } +/// The "qfga" grow array buffer is reused across multiple quickfix commands as +/// a temporary buffer to reduce the number of alloc/free calls. But if the +/// buffer size is large, then to avoid holding on to that memory, clear the +/// grow array. Otherwise just reset the grow array length. +static void qfga_clear(void) +{ + if (qfga.ga_maxlen > 1000) { + ga_clear(&qfga); + } else { + qfga.ga_len = 0; + } +} + // Counter to prevent autocmds from freeing up location lists when they are // still being used. static int quickfix_busy = 0; @@ -2847,6 +2861,8 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf msg_ext_set_kind("quickfix"); msg_attr_keep(gap->ga_data, 0, true, false); msg_scroll = (int)i; + + qfga_clear(); } /// Find a usable window for opening a file from the quickfix/location list. If @@ -3204,6 +3220,7 @@ void qf_list(exarg_T *eap) } os_breakcheck(); } + qfga_clear(); } /// Remove newlines and leading whitespace from an error message. @@ -4147,6 +4164,8 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // Delete the empty line which is now at the end (void)ml_delete(lnum + 1, false); } + + qfga_clear(); } // Correct cursor position. -- cgit From e0bbe8ccf88d4ad0667ef38ae48d8bfdabb0cc26 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 5 Mar 2023 17:04:53 +0800 Subject: vim-patch:9.0.0870: get E967 when using text property in quickfix window Problem: Get E967 when using text property in quickfix window. (Sergey Vlasov) Solution: Do not add an extra NUL and compute the text length correctly. (closes vim/vim#11513) https://github.com/vim/vim/commit/2f7bfe66a1373051792f2ecaeefb66049825221d Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 3c20c5239c..9f6181f986 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3982,6 +3982,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli // for this entry, then use it. if (qftf_str != NULL && *qftf_str != NUL) { ga_concat(gap, qftf_str); + ga_append(gap, NUL); } else { buf_T *errbuf; if (qfp->qf_module != NULL) { @@ -4024,9 +4025,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli qf_fmt_text(gap, gap->ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); } - ga_append(gap, NUL); - - if (ml_append_buf(buf, lnum, gap->ga_data, gap->ga_len + 1, false) == FAIL) { + if (ml_append_buf(buf, lnum, gap->ga_data, gap->ga_len, false) == FAIL) { return FAIL; } -- cgit From 371823d407d7d7519735131bcad4670c62a731a7 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Wed, 5 Apr 2023 21:13:53 +0200 Subject: refactor: make error message definitions const message.c functions now take const char * as a format. Error message definitions can be made const. --- src/nvim/quickfix.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 9f6181f986..c17a6366fe 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -244,10 +244,10 @@ typedef struct vgr_args_S { # include "quickfix.c.generated.h" #endif -static char *e_no_more_items = N_("E553: No more items"); -static char *e_current_quickfix_list_was_changed = +static const char *e_no_more_items = N_("E553: No more items"); +static const char *e_current_quickfix_list_was_changed = N_("E925: Current quickfix list was changed"); -static char *e_current_location_list_was_changed = +static const char *e_current_location_list_was_changed = N_("E926: Current location list was changed"); // Quickfix window check helper macro @@ -2385,7 +2385,7 @@ static qfline_T *get_nth_valid_entry(qf_list_T *qfl, int errornr, int dir, int * { qfline_T *qf_ptr = qfl->qf_ptr; int qf_idx = qfl->qf_index; - char *err = e_no_more_items; + const char *err = e_no_more_items; while (errornr--) { qfline_T *prev_qf_ptr = qf_ptr; @@ -3885,7 +3885,7 @@ static buf_T *qf_find_buf(qf_info_T *qi) } /// Process the 'quickfixtextfunc' option value. -void qf_process_qftf_option(char **errmsg) +void qf_process_qftf_option(const char **errmsg) { if (option_set_callback_func(p_qftf, &qftf_cb) == FAIL) { *errmsg = e_invarg; @@ -7304,7 +7304,7 @@ void f_getqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) static void set_qf_ll_list(win_T *wp, typval_T *args, typval_T *rettv) FUNC_ATTR_NONNULL_ARG(2, 3) { - static char *e_invact = N_("E927: Invalid action: '%s'"); + static const char *e_invact = N_("E927: Invalid action: '%s'"); const char *title = NULL; char action = ' '; static int recursive = 0; -- cgit From 9408f2dcf7cade2631688300e9b58eed6bc5219a Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 19:40:57 +0200 Subject: refactor: remove redundant const char * casts --- src/nvim/quickfix.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index c17a6366fe..8d9dc4e9c8 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5795,28 +5795,19 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) buf[0] = qfp->qf_type; buf[1] = NUL; if (tv_dict_add_nr(dict, S_LEN("bufnr"), (varnumber_T)bufnum) == FAIL - || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum) - == FAIL) - || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum) - == FAIL) + || (tv_dict_add_nr(dict, S_LEN("lnum"), (varnumber_T)qfp->qf_lnum) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_lnum"), (varnumber_T)qfp->qf_end_lnum) == FAIL) || (tv_dict_add_nr(dict, S_LEN("col"), (varnumber_T)qfp->qf_col) == FAIL) - || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col) - == FAIL) - || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) - == FAIL) + || (tv_dict_add_nr(dict, S_LEN("end_col"), (varnumber_T)qfp->qf_end_col) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("vcol"), (varnumber_T)qfp->qf_viscol) == FAIL) || (tv_dict_add_nr(dict, S_LEN("nr"), (varnumber_T)qfp->qf_nr) == FAIL) - || (tv_dict_add_str(dict, S_LEN("module"), - (qfp->qf_module == NULL ? "" : (const char *)qfp->qf_module)) - == FAIL) - || (tv_dict_add_str(dict, S_LEN("pattern"), - (qfp->qf_pattern == NULL ? "" : (const char *)qfp->qf_pattern)) + || (tv_dict_add_str(dict, S_LEN("module"), (qfp->qf_module == NULL ? "" : qfp->qf_module)) == FAIL) - || (tv_dict_add_str(dict, S_LEN("text"), - (qfp->qf_text == NULL ? "" : (const char *)qfp->qf_text)) + || (tv_dict_add_str(dict, S_LEN("pattern"), (qfp->qf_pattern == NULL ? "" : qfp->qf_pattern)) == FAIL) - || (tv_dict_add_str(dict, S_LEN("type"), (const char *)buf) == FAIL) - || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) - == FAIL)) { + || (tv_dict_add_str(dict, S_LEN("text"), (qfp->qf_text == NULL ? "" : qfp->qf_text)) == FAIL) + || (tv_dict_add_str(dict, S_LEN("type"), buf) == FAIL) + || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) == FAIL)) { // tv_dict_add* fail only if key already exist, but this is a newly // allocated dictionary which is thus guaranteed to have no existing keys. abort(); @@ -6039,8 +6030,7 @@ static int qf_getprop_qfidx(qf_info_T *qi, dict_T *what) qf_idx = INVALID_QFIDX; } } - } else if (di->di_tv.v_type == VAR_STRING - && strequal((const char *)di->di_tv.vval.v_string, "$")) { + } else if (di->di_tv.v_type == VAR_STRING && strequal(di->di_tv.vval.v_string, "$")) { // Get the last quickfix list number qf_idx = qi->qf_listcount - 1; } else { @@ -6069,7 +6059,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r int status = OK; if (flags & QF_GETLIST_TITLE) { - status = tv_dict_add_str(retdict, S_LEN("title"), (const char *)""); + status = tv_dict_add_str(retdict, S_LEN("title"), ""); } if ((status == OK) && (flags & QF_GETLIST_ITEMS)) { list_T *l = tv_list_alloc(kListLenMayKnow); @@ -6082,7 +6072,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r status = tv_dict_add_nr(retdict, S_LEN("winid"), qf_winid(qi)); } if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) { - status = tv_dict_add_str(retdict, S_LEN("context"), (const char *)""); + status = tv_dict_add_str(retdict, S_LEN("context"), ""); } if ((status == OK) && (flags & QF_GETLIST_ID)) { status = tv_dict_add_nr(retdict, S_LEN("id"), 0); @@ -6112,8 +6102,7 @@ static int qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *r /// Return the quickfix list title as 'title' in retdict static int qf_getprop_title(qf_list_T *qfl, dict_T *retdict) { - return tv_dict_add_str(retdict, S_LEN("title"), - (const char *)qfl->qf_title); + return tv_dict_add_str(retdict, S_LEN("title"), qfl->qf_title); } // Returns the identifier of the window used to display files from a location @@ -6462,8 +6451,7 @@ static int qf_setprop_get_qfidx(const qf_info_T *qi, const dict_T *what, int act } else if (action != ' ') { *newlist = false; // use the specified list } - } else if (di->di_tv.v_type == VAR_STRING - && strequal((const char *)di->di_tv.vval.v_string, "$")) { + } else if (di->di_tv.v_type == VAR_STRING && strequal(di->di_tv.vval.v_string, "$")) { if (!qf_stack_empty(qi)) { qf_idx = qi->qf_listcount - 1; } else if (*newlist) { -- cgit From 04933b1ea968f958d2541dd65fd33ebb503caac3 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:08:16 +0200 Subject: refactor: remove redundant casts --- src/nvim/quickfix.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 8d9dc4e9c8..e4b624179f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -374,8 +374,8 @@ int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, i qi = ll_get_or_alloc_list(wp); } - return qf_init_ext(qi, qi->qf_curlist, (char *)efile, curbuf, NULL, errorformat, - newlist, (linenr_T)0, (linenr_T)0, (char *)qf_title, enc); + return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, + newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); } // Maximum number of bytes allowed per line while reading an errorfile. @@ -3228,7 +3228,7 @@ void qf_list(exarg_T *eap) static void qf_fmt_text(garray_T *gap, const char *restrict text) FUNC_ATTR_NONNULL_ALL { - const char *p = (char *)text; + const char *p = text; while (*p != NUL) { if (*p == '\n') { @@ -4286,11 +4286,11 @@ static char *make_get_fullcmd(const char *makecmd, const char *fname) len += strlen(p_sp) + strlen(fname) + 3; } char *const cmd = xmalloc(len); - snprintf(cmd, len, "%s%s%s", p_shq, (char *)makecmd, p_shq); + snprintf(cmd, len, "%s%s%s", p_shq, makecmd, p_shq); // If 'shellpipe' empty: don't redirect to 'errorfile'. if (*p_sp != NUL) { - append_redir(cmd, len, p_sp, (char *)fname); + append_redir(cmd, len, p_sp, fname); } // Display the fully formed command. Output a newline if there's something @@ -7112,7 +7112,7 @@ static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char while (*p != NUL && !got_int) { copy_option_part(&p, NameBuff, MAXPATHL, ","); - hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, (char *)lang); + hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, lang); } } -- cgit From 2d78e656b715119ca11d131a1a932f22f1b4ad36 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Fri, 7 Apr 2023 21:43:00 +0200 Subject: refactor: remove redundant casts --- src/nvim/quickfix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index e4b624179f..262d87ba61 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -531,7 +531,7 @@ static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat) } } if (idx < FMT_PATTERNS) { - ptr = efmpat_to_regpat((char *)efmp, ptr, fmt_ptr, idx, round); + ptr = efmpat_to_regpat(efmp, ptr, fmt_ptr, idx, round); if (ptr == NULL) { return FAIL; } @@ -1241,7 +1241,7 @@ static char *qf_cmdtitle(char *cmd) { static char qftitle_str[IOSIZE]; - snprintf((char *)qftitle_str, IOSIZE, ":%s", cmd); + snprintf(qftitle_str, IOSIZE, ":%s", cmd); return qftitle_str; } @@ -3281,7 +3281,7 @@ static void qf_msg(qf_info_T *qi, int which, char *lead) int count = qi->qf_lists[which].qf_count; char buf[IOSIZE]; - vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "), + vim_snprintf(buf, IOSIZE, _("%serror list %d of %d; %d errors "), lead, which + 1, qi->qf_listcount, @@ -3506,7 +3506,7 @@ static char *qf_types(int c, int nr) } static char buf[20]; - snprintf((char *)buf, sizeof(buf), "%s %3d", p, nr); + snprintf(buf, sizeof(buf), "%s %3d", p, nr); return buf; } -- cgit From 8f69c5ed450337b9f77c50f9ee0d3eb32f649ca6 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Apr 2023 07:11:59 +0800 Subject: vim-patch:8.2.{0695,0725,0734,0753,0818,0819,0822} (#23075) vim-patch:8.2.0695: Vim9: cannot define a function inside a function Problem: Vim9: cannot define a function inside a function. Solution: Initial support for :def inside :def. https://github.com/vim/vim/commit/04b12697838b232b8b17c553ccc74cf1f1bdb81c vim-patch:8.2.0725: Vim9: cannot call a function declared later in Vim9 script Problem: Vim9: cannot call a function declared later in Vim9 script. Solution: Make two passes through the script file. https://github.com/vim/vim/commit/09689a02840be40fa7bb10b1921fb5bc5b2908f1 vim-patch:8.2.0734: Vim9: leaking memory when using :finish Problem: Vim9: leaking memory when using :finish. Solution: Do not check for next line in third pass. https://github.com/vim/vim/commit/04816717dfea6e2469ff4c9d40f68b59aaf03724 vim-patch:8.2.0753: Vim9: expressions are evaluated in the discovery phase Problem: Vim9: expressions are evaluated in the discovery phase. Solution: Bail out if an expression is not a constant. Require a type for declared constants. https://github.com/vim/vim/commit/32e351179eacfc84f64cd5029e221582d400bb38 vim-patch:8.2.0818: Vim9: using a discovery phase doesn't work well Problem: Vim9: using a discovery phase doesn't work well. Solution: Remove the discovery phase, instead compile a function only when it is used. Add :defcompile to compile def functions earlier. https://github.com/vim/vim/commit/822ba24743af9ee1b5e7f656a7a61a38f3638bca vim-patch:8.2.0819: compiler warning for unused variable Problem: Compiler warning for unused variable. Solution: Remove the variable. https://github.com/vim/vim/commit/f40e51a880a95f94dbbbecc9476559506c2cc345 vim-patch:8.2.0822: Vim9: code left over from discovery phase Problem: Vim9: code left over from discovery phase. Solution: Remove the dead code. https://github.com/vim/vim/commit/2eec37926db6d31beb36f162ac00357a30c093c8 Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 262d87ba61..cfaa3b5781 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6958,7 +6958,7 @@ void ex_cexpr(exarg_T *eap) // Evaluate the expression. When the result is a string or a list we can // use it to fill the errorlist. typval_T tv; - if (eval0(eap->arg, &tv, &eap->nextcmd, true) == FAIL) { + if (eval0(eap->arg, &tv, &eap->nextcmd, EVAL_EVALUATE) == FAIL) { return; } -- cgit From bd83b587b18bb6f2ac555a992fa5b7d907de7e79 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Apr 2023 07:22:01 +0800 Subject: vim-patch:8.2.1047: Vim9: script cannot use line continuation like :def function Problem: Vim9: script cannot use line continuation like in a :def function. Solution: Pass the getline function pointer to the eval() functions. Use it for addition and multiplication operators. https://github.com/vim/vim/commit/5409f5d8c95007216ae1190565a7a8ee9ebd7100 Omit source_nextline() and eval_next_non_blank(): Vim9 script only. N/A patches for version.c: vim-patch:8.2.1048: build failure without the eval feature Problem: Build failure without the eval feature. Solution: Add dummy typedef. https://github.com/vim/vim/commit/9d40c63c7dc8c3eb3886c58dcd334bc7f37eceba vim-patch:8.2.1052: build failure with older compilers Problem: Build failure with older compilers. Solution: Move declaration to start of block. https://github.com/vim/vim/commit/7acde51832f383f9a6d2e740cd0420b433ea841a Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index cfaa3b5781..38e05f408e 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6958,7 +6958,7 @@ void ex_cexpr(exarg_T *eap) // Evaluate the expression. When the result is a string or a list we can // use it to fill the errorlist. typval_T tv; - if (eval0(eap->arg, &tv, &eap->nextcmd, EVAL_EVALUATE) == FAIL) { + if (eval0(eap->arg, &tv, &eap->nextcmd, &EVALARG_EVALUATE) == FAIL) { return; } -- cgit From 8e2903d2fe810cfa3be41fc1e7a4d8394c84cf11 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Apr 2023 09:11:37 +0800 Subject: vim-patch:8.2.1049: Vim9: leaking memory when using continuation line Problem: Vim9: leaking memory when using continuation line. Solution: Keep a pointer to the continuation line in evalarg_T. Centralize checking for a next command. https://github.com/vim/vim/commit/b171fb179053fa631fec74911b5fb9374cb6a8a1 Omit eval_next_line(): Vim9 script only. vim-patch:8.2.1050: missing change in struct Problem: Missing change in struct. Solution: Add missing change. https://github.com/vim/vim/commit/65a8ed37f7bc61fbe5c612a7b0eb0dfc16ad3e11 Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 38e05f408e..fdcdd71ceb 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6958,7 +6958,7 @@ void ex_cexpr(exarg_T *eap) // Evaluate the expression. When the result is a string or a list we can // use it to fill the errorlist. typval_T tv; - if (eval0(eap->arg, &tv, &eap->nextcmd, &EVALARG_EVALUATE) == FAIL) { + if (eval0(eap->arg, &tv, eap, &EVALARG_EVALUATE) == FAIL) { return; } -- cgit From 8729c41f44de3b164ad8d01bb3558c6400e27952 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 14 Apr 2023 13:49:28 +0800 Subject: vim-patch:8.2.1080: Vim9: no line break allowed in a for loop Problem: Vim9: no line break allowed in a for loop. Solution: Skip line breaks in for command. https://github.com/vim/vim/commit/b7a78f7a6713f07d2fcad0b27dea22925c7b1cdf Omit *_break_count and skip_for_lines(): Vim9 script only. Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index fdcdd71ceb..62eb14342c 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -6957,15 +6957,15 @@ void ex_cexpr(exarg_T *eap) // Evaluate the expression. When the result is a string or a list we can // use it to fill the errorlist. - typval_T tv; - if (eval0(eap->arg, &tv, eap, &EVALARG_EVALUATE) == FAIL) { + typval_T *tv = eval_expr(eap->arg, eap); + if (tv == NULL) { return; } - if ((tv.v_type == VAR_STRING && tv.vval.v_string != NULL) - || tv.v_type == VAR_LIST) { + if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) + || tv->v_type == VAR_LIST) { incr_quickfix_busy(); - int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, &tv, p_efm, + int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm, (eap->cmdidx != CMD_caddexpr && eap->cmdidx != CMD_laddexpr), (linenr_T)0, (linenr_T)0, @@ -6996,7 +6996,7 @@ void ex_cexpr(exarg_T *eap) emsg(_("E777: String or List expected")); } cleanup: - tv_clear(&tv); + tv_free(tv); } // Get the location list for ":lhelpgrep" -- cgit From 3b0df1780e2c8526bda5dead18ee7cc45925caba Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:23:44 +0200 Subject: refactor: uncrustify Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`. --- src/nvim/quickfix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 62eb14342c..36714d816a 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -800,7 +800,7 @@ retry: memcpy(state->growbuf, IObuff, IOSIZE - 1); size_t growbuflen = state->linelen; - for (;;) { + while (true) { errno = 0; if (fgets(state->growbuf + growbuflen, (int)(state->growbufsiz - growbuflen), state->fd) == NULL) { @@ -2291,7 +2291,7 @@ static char *qf_guess_filepath(qf_list_T *qfl, char *filename) } /// Returns true, if a quickfix/location list with the given identifier exists. -static bool qflist_valid(win_T *wp, unsigned int qf_id) +static bool qflist_valid(win_T *wp, unsigned qf_id) { qf_info_T *qi = &ql_info; @@ -2641,7 +2641,7 @@ static void qf_goto_win_with_qfl_file(int qf_fnum) { win_T *win = curwin; win_T *altwin = NULL; - for (;;) { + while (true) { if (win->w_buffer->b_fnum == qf_fnum) { break; } @@ -4414,7 +4414,7 @@ static char *get_mef_name(void) } // Keep trying until the name doesn't exist yet. - for (;;) { + while (true) { if (start == -1) { start = (int)os_get_pid(); } else { -- cgit From ff34c91194f9ab9d02808f2880029c38a4655eb5 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 17 Apr 2023 17:23:47 +0100 Subject: vim-patch:9.0.1330: handling new value of an option has a long "else if" chain Problem: Handling new value of an option has a long "else if" chain. Solution: Use a function pointer. (Yegappan Lakshmanan, closes vim/vim#12015) https://github.com/vim/vim/commit/af93691b53f38784efce0b93fe7644c44a7e382e --- src/nvim/quickfix.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 36714d816a..48a558197f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3885,11 +3885,12 @@ static buf_T *qf_find_buf(qf_info_T *qi) } /// Process the 'quickfixtextfunc' option value. -void qf_process_qftf_option(const char **errmsg) +const char *did_set_quickfixtextfunc(optset_T *args FUNC_ATTR_UNUSED) { if (option_set_callback_func(p_qftf, &qftf_cb) == FAIL) { - *errmsg = e_invarg; + return e_invarg; } + return NULL; } /// Update the w:quickfix_title variable in the quickfix/location list window in -- cgit From ab7dcefbebf5a483845e1fe1c82cb32e1c6418d4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 30 Apr 2023 08:27:38 +0800 Subject: vim-patch:9.0.1499: using uninitialized memory with fuzzy matching (#23399) Problem: Using uninitialized memory with fuzzy matching. Solution: Initialize the arrays used to store match positions. https://github.com/vim/vim/commit/caf642c25de526229264cab9425e7c9979f3509b Co-authored-by: Bram Moolenaar --- src/nvim/quickfix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 48a558197f..d6bbcbc80d 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5215,7 +5215,10 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5, 6) { bool found_match = false; - const size_t pat_len = strlen(spat); + size_t pat_len = strlen(spat); + if (pat_len > MAX_FUZZY_MATCHES) { + pat_len = MAX_FUZZY_MATCHES; + } for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; lnum++) { colnr_T col = 0; @@ -5263,6 +5266,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp const size_t sz = sizeof(matches) / sizeof(matches[0]); // Fuzzy string match + CLEAR_FIELD(matches); while (fuzzy_match(str + col, spat, false, &score, matches, (int)sz) > 0) { // Pass the buffer number so that it gets used even for a // dummy buffer, unless duplicate_name is set, then the -- cgit From b3d5138fd0066fda26ef7724a542ae45eb42fc84 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 7 Jun 2023 06:05:16 +0600 Subject: refactor(options): remove `getoption_T` and introduce `OptVal` (#23850) Removes the `getoption_T` struct and also introduces the `OptVal` struct to unify the methods of getting/setting different option value types. This is the first of many PRs to reduce code duplication in the Vim option code as well as to make options easier to maintain. It also increases the flexibility and extensibility of options. Which opens the door for things like Array and Dictionary options. --- src/nvim/quickfix.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index d6bbcbc80d..8a78a3cd80 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3612,12 +3612,12 @@ static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsp static void qf_set_cwindow_options(void) { // switch off 'swapfile' - set_option_value_give_err("swf", 0L, NULL, OPT_LOCAL); - set_option_value_give_err("bt", 0L, "quickfix", OPT_LOCAL); - set_option_value_give_err("bh", 0L, "hide", OPT_LOCAL); + set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); + set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); RESET_BINDING(curwin); curwin->w_p_diff = false; - set_option_value_give_err("fdm", 0L, "manual", OPT_LOCAL); + set_option_value_give_err("fdm", STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); } // Open a new quickfix or location list window, load the quickfix buffer and @@ -4176,7 +4176,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // resembles reading a file into a buffer, it's more logical when using // autocommands. curbuf->b_ro_locked++; - set_option_value_give_err("ft", 0L, "qf", OPT_LOCAL); + set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); curbuf->b_p_ma = false; keep_filetype = true; // don't detect 'filetype' @@ -7183,7 +7183,7 @@ void ex_helpgrep(exarg_T *eap) // Darn, some plugin changed the value. If it's still empty it was // changed and restored, need to restore in the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", 0L, save_cpo, 0); + set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); } if (save_cpo_allocated) { free_string_option(save_cpo); -- cgit From 38b0bb3c93022afcc54c0891d2eced02d2a9fa3a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 8 Jun 2023 07:03:22 +0800 Subject: vim-patch:9.0.1616: quickfix text field is truncated (#23951) Problem: Quickfix text field is truncated. Solution: Fix output of text field after pattern field in quickfix buffer. (Shane Harper, closes vim/vim#12498) https://github.com/vim/vim/commit/5bf042810b19a627eda2f170624a0cfd7b4f6ed6 Co-authored-by: Shane Harper --- src/nvim/quickfix.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 8a78a3cd80..90dac4d3bf 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2848,6 +2848,7 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf // Add the message, skipping leading whitespace and newlines. ga_concat(gap, IObuff); qf_fmt_text(gap, skipwhite(qf_ptr->qf_text)); + ga_append(gap, NUL); // Output the message. Overwrite to avoid scrolling when the 'O' // flag is present in 'shortmess'; But when not jumping, print the @@ -3123,9 +3124,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) msg_puts_attr(":", qfSepAttr); } garray_T *gap = qfga_get(); - if (qfp->qf_lnum == 0) { - ga_append(gap, NUL); - } else { + if (qfp->qf_lnum != 0) { qf_range_text(gap, qfp); } ga_concat(gap, qf_types(qfp->qf_type, qfp->qf_nr)); @@ -3135,6 +3134,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) if (qfp->qf_pattern != NULL) { gap = qfga_get(); qf_fmt_text(gap, qfp->qf_pattern); + ga_append(gap, NUL); msg_puts(gap->ga_data); msg_puts_attr(":", qfSepAttr); } @@ -3145,6 +3145,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) // with ^^^^. gap = qfga_get(); qf_fmt_text(gap, (fname != NULL || qfp->qf_lnum != 0) ? skipwhite(qfp->qf_text) : qfp->qf_text); + ga_append(gap, NUL); msg_prt_line(gap->ga_data, false); } @@ -3229,7 +3230,6 @@ static void qf_fmt_text(garray_T *gap, const char *restrict text) FUNC_ATTR_NONNULL_ALL { const char *p = text; - while (*p != NUL) { if (*p == '\n') { ga_append(gap, ' '); @@ -3242,8 +3242,6 @@ static void qf_fmt_text(garray_T *gap, const char *restrict text) ga_append(gap, (uint8_t)(*p++)); } } - - ga_append(gap, NUL); } /// Add the range information from the lnum, col, end_lnum, and end_col values @@ -3268,7 +3266,6 @@ static void qf_range_text(garray_T *gap, const qfline_T *qfp) len += strlen(buf + len); } } - buf[len] = NUL; ga_concat_len(gap, buf, len); } @@ -3983,7 +3980,6 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli // for this entry, then use it. if (qftf_str != NULL && *qftf_str != NUL) { ga_concat(gap, qftf_str); - ga_append(gap, NUL); } else { buf_T *errbuf; if (qfp->qf_module != NULL) { @@ -4026,6 +4022,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli qf_fmt_text(gap, gap->ga_len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text); } + ga_append(gap, NUL); if (ml_append_buf(buf, lnum, gap->ga_data, gap->ga_len, false) == FAIL) { return FAIL; } -- cgit From 2f17ef1fc4b96cf1106fd95ba090d34a2e4b977b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 22 Jun 2023 04:09:14 -0700 Subject: fix(messages): use "Vimscript" instead of "VimL" #24111 followup to #24109 fix #16150 --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 90dac4d3bf..d42e0ed24f 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -7276,7 +7276,7 @@ void f_getqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) get_qf_loc_list(true, NULL, &argvars[0], rettv); } -/// Create quickfix/location list from VimL values +/// Create quickfix/location list from Vimscript values /// /// Used by `setqflist()` and `setloclist()` functions. Accepts invalid /// args argument in which case errors out, including VAR_UNKNOWN parameters. -- cgit From 6c07a189f2d10a533af8a51819ea96c45e0c567e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 12 Aug 2023 08:19:06 +0800 Subject: vim-patch:9.0.1688: cannot store custom data in quickfix list (#24673) Problem: cannot store custom data in quickfix list Solution: add `user_data` field for the quickfix list closes: vim/vim#11818 https://github.com/vim/vim/commit/ca6ac99077d2e6d020a34267aa5e0fbc4d23dc38 Co-authored-by: Tom Praschan <13141438+tom-anders@users.noreply.github.com> --- src/nvim/quickfix.c | 106 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 26 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index d42e0ed24f..00a9dad1fe 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -80,14 +80,14 @@ struct qfline_S { int qf_col; ///< column where the error occurred int qf_end_col; ///< column when the error has range or zero int qf_nr; ///< error number - char *qf_module; ///< module name for this error - char *qf_pattern; ///< search pattern for the error - char *qf_text; ///< description of the error - char qf_viscol; ///< set to true if qf_col and qf_end_col is - // screen column - char qf_cleared; ///< set to true if line has been deleted - char qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep - char qf_valid; ///< valid error message detected + char *qf_module; ///< module name for this error + char *qf_pattern; ///< search pattern for the error + char *qf_text; ///< description of the error + char qf_viscol; ///< set to true if qf_col and qf_end_col is screen column + char qf_cleared; ///< set to true if line has been deleted + char qf_type; ///< type of the error (mostly 'E'); 1 for :helpgrep + typval_T qf_user_data; ///< custom user data associated with this item + char qf_valid; ///< valid error message detected }; // There is a stack of error lists. @@ -109,18 +109,19 @@ typedef enum { /// created using setqflist()/setloclist() with a title and/or user context /// information and entries can be added later using setqflist()/setloclist(). typedef struct qf_list_S { - unsigned qf_id; ///< Unique identifier for this list + unsigned qf_id; ///< Unique identifier for this list qfltype_T qfl_type; - qfline_T *qf_start; ///< pointer to the first error - qfline_T *qf_last; ///< pointer to the last error - qfline_T *qf_ptr; ///< pointer to the current error - int qf_count; ///< number of errors (0 means empty list) - int qf_index; ///< current index in the error list - int qf_nonevalid; ///< true if not a single valid entry found - char *qf_title; ///< title derived from the command that created - ///< the error list or set by setqflist - typval_T *qf_ctx; ///< context set by setqflist/setloclist - Callback qf_qftf_cb; ///< 'quickfixtextfunc' callback function + qfline_T *qf_start; ///< pointer to the first error + qfline_T *qf_last; ///< pointer to the last error + qfline_T *qf_ptr; ///< pointer to the current error + int qf_count; ///< number of errors (0 means empty list) + int qf_index; ///< current index in the error list + bool qf_nonevalid; ///< true if not a single valid entry found + bool qf_has_user_data; ///< true if at least one item has user_data attached + char *qf_title; ///< title derived from the command that created + ///< the error list or set by setqflist + typval_T *qf_ctx; ///< context set by setqflist/setloclist + Callback qf_qftf_cb; ///< 'quickfixtextfunc' callback function struct dir_stack_T *qf_dir_stack; char *qf_directory; @@ -226,6 +227,7 @@ typedef struct { char *pattern; int enr; char type; + typval_T *user_data; bool valid; } qffields_T; @@ -351,6 +353,7 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T fields->pattern, fields->enr, fields->type, + fields->user_data, fields->valid); } @@ -1281,6 +1284,7 @@ static void qf_new_list(qf_info_T *qi, const char *qf_title) qf_store_title(qfl, qf_title); qfl->qfl_type = qi->qfl_type; qfl->qf_id = ++last_qf_id; + qfl->qf_has_user_data = false; } /// Parse the match for filename ('%f') pattern in regmatch. @@ -1836,12 +1840,14 @@ void check_quickfix_busy(void) /// @param pattern search pattern /// @param nr error number /// @param type type character +/// @param user_data custom user data or NULL /// @param valid valid entry /// /// @return QF_OK on success or QF_FAIL on failure. static int qf_add_entry(qf_list_T *qfl, char *dir, char *fname, char *module, int bufnum, char *mesg, linenr_T lnum, linenr_T end_lnum, int col, int end_col, - char vis_col, char *pattern, int nr, char type, char valid) + char vis_col, char *pattern, int nr, char type, typval_T *user_data, + char valid) { qfline_T *qfp = xmalloc(sizeof(qfline_T)); @@ -1862,6 +1868,12 @@ static int qf_add_entry(qf_list_T *qfl, char *dir, char *fname, char *module, in qfp->qf_col = col; qfp->qf_end_col = end_col; qfp->qf_viscol = vis_col; + if (user_data == NULL || user_data->v_type == VAR_UNKNOWN) { + qfp->qf_user_data.v_type = VAR_UNKNOWN; + } else { + tv_copy(user_data, &qfp->qf_user_data); + qfl->qf_has_user_data = true; + } if (pattern == NULL || *pattern == NUL) { qfp->qf_pattern = NULL; } else { @@ -1997,6 +2009,7 @@ static int copy_loclist_entries(const qf_list_T *from_qfl, qf_list_T *to_qfl) from_qfp->qf_pattern, from_qfp->qf_nr, 0, + &from_qfp->qf_user_data, from_qfp->qf_valid) == QF_FAIL) { return FAIL; } @@ -2022,6 +2035,7 @@ static int copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl) // Some of the fields are populated by qf_add_entry() to_qfl->qfl_type = from_qfl->qfl_type; to_qfl->qf_nonevalid = from_qfl->qf_nonevalid; + to_qfl->qf_has_user_data = from_qfl->qf_has_user_data; to_qfl->qf_count = 0; to_qfl->qf_index = 0; to_qfl->qf_start = NULL; @@ -3374,6 +3388,7 @@ static void qf_free_items(qf_list_T *qfl) xfree(qfp->qf_module); xfree(qfp->qf_text); xfree(qfp->qf_pattern); + tv_clear(&qfp->qf_user_data); stop = (qfp == qfpnext); xfree(qfp); if (stop) { @@ -5239,6 +5254,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp NULL, // search pattern 0, // nr 0, // type + NULL, // user_data true) // valid == QF_FAIL) { got_int = true; @@ -5282,6 +5298,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp NULL, // search pattern 0, // nr 0, // type + NULL, // user_data true) // valid == QF_FAIL) { got_int = true; @@ -5809,6 +5826,8 @@ static int get_qfline_items(qfline_T *qfp, list_T *list) == FAIL) || (tv_dict_add_str(dict, S_LEN("text"), (qfp->qf_text == NULL ? "" : qfp->qf_text)) == FAIL) || (tv_dict_add_str(dict, S_LEN("type"), buf) == FAIL) + || (qfp->qf_user_data.v_type != VAR_UNKNOWN + && tv_dict_add_tv(dict, S_LEN("user_data"), &qfp->qf_user_data) == FAIL) || (tv_dict_add_nr(dict, S_LEN("valid"), (varnumber_T)qfp->qf_valid) == FAIL)) { // tv_dict_add* fail only if key already exist, but this is a newly // allocated dictionary which is thus guaranteed to have no existing keys. @@ -6288,8 +6307,7 @@ static int qf_setprop_qftf(qf_list_T *qfl, dictitem_T *di) /// Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the /// items in the dict 'd'. If it is a valid error entry, then set 'valid_entry' /// to true. -static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_entry, - bool *valid_entry) +static int qf_add_entry_from_dict(qf_list_T *qfl, dict_T *d, bool first_entry, bool *valid_entry) FUNC_ATTR_NONNULL_ALL { static bool did_bufnr_emsg; @@ -6313,6 +6331,9 @@ static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_en if (text == NULL) { text = xcalloc(1, 1); } + typval_T user_data = { .v_type = VAR_UNKNOWN }; + tv_dict_get_tv(d, "user_data", &user_data); + bool valid = true; if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL)) { @@ -6349,12 +6370,14 @@ static int qf_add_entry_from_dict(qf_list_T *qfl, const dict_T *d, bool first_en pattern, // search pattern nr, type == NULL ? NUL : *type, + &user_data, valid); xfree(filename); xfree(module); xfree(pattern); xfree(text); + tv_clear(&user_data); if (valid) { *valid_entry = true; @@ -6390,13 +6413,12 @@ static int qf_add_entries(qf_info_T *qi, int qf_idx, list_T *list, char *title, continue; // Skip non-dict items. } - const dict_T *const d = TV_LIST_ITEM_TV(li)->vval.v_dict; + dict_T *const d = TV_LIST_ITEM_TV(li)->vval.v_dict; if (d == NULL) { continue; } - retval = qf_add_entry_from_dict(qfl, d, li == tv_list_first(list), - &valid_entry); + retval = qf_add_entry_from_dict(qfl, d, li == tv_list_first(list), &valid_entry); if (retval == QF_FAIL) { break; } @@ -6734,6 +6756,27 @@ int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what return retval; } +static bool mark_quickfix_user_data(qf_info_T *qi, int copyID) +{ + bool abort = false; + for (int i = 0; i < LISTCOUNT && !abort; i++) { + qf_list_T *qfl = &qi->qf_lists[i]; + if (!qfl->qf_has_user_data) { + continue; + } + qfline_T *qfp; + int j; + FOR_ALL_QFL_ITEMS(qfl, qfp, j) { + typval_T *user_data = &qfp->qf_user_data; + if (user_data != NULL && user_data->v_type != VAR_NUMBER + && user_data->v_type != VAR_STRING && user_data->v_type != VAR_FLOAT) { + abort = abort || set_ref_in_item(user_data, copyID, NULL, NULL); + } + } + } + return abort; +} + /// Mark the quickfix context and callback function as in use for all the lists /// in a quickfix stack. static bool mark_quickfix_ctx(qf_info_T *qi, int copyID) @@ -6763,6 +6806,11 @@ bool set_ref_in_quickfix(int copyID) return abort; } + abort = mark_quickfix_user_data(&ql_info, copyID); + if (abort) { + return abort; + } + abort = set_ref_in_callback(&qftf_cb, copyID, NULL, NULL); if (abort) { return abort; @@ -6774,6 +6822,11 @@ bool set_ref_in_quickfix(int copyID) if (abort) { return abort; } + + abort = mark_quickfix_user_data(win->w_llist, copyID); + if (abort) { + return abort; + } } if (IS_LL_WINDOW(win) && (win->w_llist_ref->qf_refcount == 1)) { @@ -7054,7 +7107,8 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch) NULL, // search pattern 0, // nr 1, // type - true) // valid + NULL, // user_data + true) // valid == QF_FAIL) { got_int = true; if (line != IObuff) { -- cgit From cefd774fac76b91f5368833555818c80c992c3b1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 24 Aug 2023 15:14:23 +0200 Subject: refactor(memline): distinguish mutating uses of ml_get_buf() ml_get_buf() takes a third parameters to indicate whether the caller wants to mutate the memline data in place. However the vast majority of the call sites is using this function just to specify a buffer but without any mutation. This makes it harder to grep for the places which actually perform mutation. Solution: Remove the bool param from ml_get_buf(). it now works like ml_get() except for a non-current buffer. Add a new ml_get_buf_mut() function for the mutating use-case, which can be grepped along with the other ml_replace() etc functions which can modify the memline. --- src/nvim/quickfix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 00a9dad1fe..2152e79536 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -761,7 +761,7 @@ static int qf_get_next_buf_line(qfstate_T *state) if (state->buflnum > state->lnumlast) { return QF_END_OF_INPUT; } - char *p_buf = ml_get_buf(state->buf, state->buflnum, false); + char *p_buf = ml_get_buf(state->buf, state->buflnum); state->buflnum += 1; size_t len = strlen(p_buf); @@ -5245,7 +5245,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp fname, NULL, duplicate_name ? 0 : buf->b_fnum, - ml_get_buf(buf, regmatch->startpos[0].lnum + lnum, false), + ml_get_buf(buf, regmatch->startpos[0].lnum + lnum), regmatch->startpos[0].lnum + lnum, regmatch->endpos[0].lnum + lnum, regmatch->startpos[0].col + 1, @@ -5268,12 +5268,12 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp break; } col = regmatch->endpos[0].col + (col == regmatch->endpos[0].col); - if (col > (colnr_T)strlen(ml_get_buf(buf, lnum, false))) { + if (col > (colnr_T)strlen(ml_get_buf(buf, lnum))) { break; } } } else { - char *const str = ml_get_buf(buf, lnum, false); + char *const str = ml_get_buf(buf, lnum); int score; uint32_t matches[MAX_FUZZY_MATCHES]; const size_t sz = sizeof(matches) / sizeof(matches[0]); -- cgit From 008154954791001efcc46c28146e21403f3a698b Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 21 Aug 2023 14:52:17 +0200 Subject: refactor(change): do API changes to buffer without curbuf switch Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about `curwin`. When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin. But this means if two or more non-current windows displayed the buffers, one of them will be treated differenty. this is not desirable. In particular, with nvim_buf_set_text, cursor _column_ position was only corrected for one single window. Two new tests are added: the test with just one non-current window passes, but the one with two didn't. Two corresponding such tests were also added for nvim_buf_set_lines. This already worked correctly on master, but make sure this is well-tested for future refactors. Also, nvim_create_buf no longer invokes autocmds just because you happened to use `scratch=true`. No option value was changed, therefore OptionSet must not be fired. --- src/nvim/quickfix.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 2152e79536..70fcf3d276 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3433,14 +3433,17 @@ static void qf_free(qf_list_T *qfl) qfl->qf_changedtick = 0L; } -// qf_mark_adjust: adjust marks -bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount, +/// Adjust error list entries for changed line numbers +/// +/// Note: `buf` is the changed buffer, but `wp` is a potential location list +/// into that buffer, or NULL to check the quickfix list. +bool qf_mark_adjust(buf_T *buf, win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after) { qf_info_T *qi = &ql_info; int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; - if (!(curbuf->b_has_qf_entry & buf_has_flag)) { + if (!(buf->b_has_qf_entry & buf_has_flag)) { return false; } if (wp != NULL) { @@ -3457,7 +3460,7 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount, 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) { + if (qfp->qf_fnum == buf->b_fnum) { found_one = true; if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) { if (amount == MAXLNUM) { -- cgit From f91cd31d7d9d70006e0000592637d5d997eab52c Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 27 Sep 2023 21:46:39 +0200 Subject: refactor(messages): fold msg_outtrans_attr into msg_outtrans problem: there are too many different functions in message.c solution: fold some of the functions into themselves --- src/nvim/quickfix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 70fcf3d276..39cb974e95 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3132,7 +3132,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel) } msg_putchar('\n'); - msg_outtrans_attr(IObuff, cursel ? HL_ATTR(HLF_QFL) : qfFileAttr); + msg_outtrans(IObuff, cursel ? HL_ATTR(HLF_QFL) : qfFileAttr); if (qfp->qf_lnum != 0) { msg_puts_attr(":", qfSepAttr); @@ -4317,7 +4317,7 @@ static char *make_get_fullcmd(const char *makecmd, const char *fname) } msg_start(); msg_puts(":!"); - msg_outtrans(cmd); // show what we are doing + msg_outtrans(cmd, 0); // show what we are doing return cmd; } @@ -5168,9 +5168,9 @@ static void vgr_display_fname(char *fname) msg_start(); char *p = msg_strtrunc(fname, true); if (p == NULL) { - msg_outtrans(fname); + msg_outtrans(fname, 0); } else { - msg_outtrans(p); + msg_outtrans(p, 0); xfree(p); } msg_clr_eos(); -- cgit From b85f1dafc7c0a19704135617454f1c66f41202c1 Mon Sep 17 00:00:00 2001 From: bfredl Date: Wed, 27 Sep 2023 22:21:17 +0200 Subject: refactor(messages): fold msg_attr into msg problem: there are too many different functions in message.c solution: fold some of the functions into themselves --- src/nvim/quickfix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 39cb974e95..54d0262f90 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3308,7 +3308,7 @@ static void qf_msg(qf_info_T *qi, int which, char *lead) xstrlcat(buf, title, IOSIZE); } trunc_string(buf, buf, Columns - 1, IOSIZE); - msg(buf); + msg(buf, 0); } /// ":colder [count]": Up in the quickfix stack. @@ -3367,7 +3367,7 @@ void qf_history(exarg_T *eap) } if (qf_stack_empty(qi)) { - msg(_("No entries")); + msg(_("No entries"), 0); } else { for (int i = 0; i < qi->qf_listcount; i++) { qf_msg(qi, i, i == qi->qf_curlist ? "> " : " "); -- cgit From af7d317f3ff31d5ac5d8724b5057a422e1451b54 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 26 Sep 2023 22:36:08 +0200 Subject: refactor: remove long long is 32-bits even on 64-bit windows which makes the type suboptimal for a codebase meant to be cross-platform. --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 54d0262f90..b0c6fd79e2 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5187,7 +5187,7 @@ static buf_T *vgr_load_dummy_buf(char *fname, char *dirname_start, char *dirname // indent scripts, a great speed improvement. char *save_ei = au_event_disable(",Filetype"); - long save_mls = p_mls; + OptInt save_mls = p_mls; p_mls = 0; // Load file into a buffer, so that 'fileencoding' is detected, -- cgit From bc13bc154aa574e0bb58a50f2e0ca4570efa57c3 Mon Sep 17 00:00:00 2001 From: bfredl Date: Fri, 29 Sep 2023 16:10:54 +0200 Subject: refactor(message): smsg_attr -> smsg --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index b0c6fd79e2..a02c0eface 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5458,7 +5458,7 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo if (buf == NULL) { if (!got_int) { - smsg(_("Cannot open file \"%s\""), fname); + smsg(0, _("Cannot open file \"%s\""), fname); } } else { // Try for a match in all lines of the buffer. -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/quickfix.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index a02c0eface..fc2259f9ff 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -23,7 +23,6 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" -#include "nvim/eval/typval_defs.h" #include "nvim/eval/window.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" @@ -33,6 +32,7 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/help.h" @@ -41,7 +41,6 @@ #include "nvim/macros.h" #include "nvim/mark.h" #include "nvim/mbyte.h" -#include "nvim/memfile_defs.h" #include "nvim/memline.h" #include "nvim/memory.h" #include "nvim/message.h" -- cgit From dc6d0d2daf69e2fdadda81feb97906dbc962a239 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 14:41:34 +0800 Subject: refactor: reorganize option header files (#25437) - Move vimoption_T to option.h - option_defs.h is for option-related types - option_vars.h corresponds to Vim's option.h - option_defs.h and option_vars.h don't include each other --- src/nvim/quickfix.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index fc2259f9ff..e6d5831dd3 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -47,6 +47,8 @@ #include "nvim/move.h" #include "nvim/normal.h" #include "nvim/option.h" +#include "nvim/option_defs.h" +#include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/fs_defs.h" #include "nvim/os/input.h" -- cgit From 8e932480f61d6101bf8bea1abc07ed93826221fd Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 29 Sep 2023 14:58:48 +0200 Subject: refactor: the long goodbye long is 32 bits on windows, while it is 64 bits on other architectures. This makes the type suboptimal for a codebase meant to be cross-platform. Replace it with more appropriate integer types. --- src/nvim/quickfix.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index e6d5831dd3..c532c08572 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -131,7 +131,7 @@ typedef struct qf_list_S { bool qf_multiline; bool qf_multiignore; bool qf_multiscan; - long qf_changedtick; + int qf_changedtick; } qf_list_T; /// Quickfix/Location list stack definition @@ -234,7 +234,7 @@ typedef struct { /// :vimgrep command arguments typedef struct vgr_args_S { - long tomatch; ///< maximum number of matches to find + int tomatch; ///< maximum number of matches to find char *spat; ///< search pattern int flags; ///< search modifier char **fnames; ///< list of files to search @@ -2756,7 +2756,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); - long old_changetick = qfl->qf_changedtick; + int old_changetick = qfl->qf_changedtick; int old_qf_curlist = qi->qf_curlist; qfltype_T qfl_type = qfl->qfl_type; int retval = OK; @@ -2836,7 +2836,7 @@ static void qf_jump_goto_line(linenr_T qf_lnum, int qf_col, char qf_viscol, char // Move the cursor to the first line in the buffer pos_T save_cursor = curwin->w_cursor; curwin->w_cursor.lnum = 0; - if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) { + if (!do_search(NULL, '/', '/', qf_pattern, 1, SEARCH_KEEP, NULL)) { curwin->w_cursor = save_cursor; } } @@ -2891,7 +2891,7 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int *opened_window) { qf_list_T *qfl = qf_get_curlist(qi); - long old_changetick = qfl->qf_changedtick; + int old_changetick = qfl->qf_changedtick; int old_qf_curlist = qi->qf_curlist; qfltype_T qfl_type = qfl->qfl_type; @@ -4051,7 +4051,7 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli // Call the 'quickfixtextfunc' function to get the list of lines to display in // the quickfix window for the entries 'start_idx' to 'end_idx'. -static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx) +static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, int start_idx, int end_idx) { Callback *cb = &qftf_cb; list_T *qftf_list = NULL; @@ -4142,7 +4142,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q lnum = buf->b_ml.ml_line_count; } - list_T *qftf_list = call_qftf_func(qfl, qf_winid, lnum + 1, (long)qfl->qf_count); + list_T *qftf_list = call_qftf_func(qfl, qf_winid, lnum + 1, qfl->qf_count); listitem_T *qftf_li = tv_list_first(qftf_list); int prev_bufnr = -1; @@ -5227,7 +5227,7 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char *titl /// Search for a pattern in all the lines in a buffer and add the matching lines /// to a quickfix list. static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *spat, - regmmatch_T *regmatch, long *tomatch, int duplicate_name, int flags) + regmmatch_T *regmatch, int *tomatch, int duplicate_name, int flags) FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5, 6) { bool found_match = false; -- cgit From af010e23f38a23bb74ea5b61e1b1a05e76410b5f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Fri, 13 Oct 2023 20:16:15 +0600 Subject: refactor(options): rename `empty_option` to `empty_string_option` --- src/nvim/quickfix.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index c532c08572..5616a5a048 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2596,7 +2596,7 @@ static int qf_open_new_file_win(qf_info_T *ll_ref) if (win_split(0, flags) == FAIL) { return FAIL; // not enough room for window } - p_swb = empty_option; // don't split again + p_swb = empty_string_option; // don't split again swb_flags = 0; RESET_BINDING(curwin); if (ll_ref != NULL) { @@ -3073,7 +3073,7 @@ theend: qfl->qf_ptr = qf_ptr; qfl->qf_index = qf_index; } - if (p_swb != old_swb && p_swb == empty_option) { + if (p_swb != old_swb && p_swb == empty_string_option) { // Restore old 'switchbuf' value, but not when an autocommand or // modeline has changed the value. p_swb = old_swb; @@ -7201,7 +7201,7 @@ void ex_helpgrep(exarg_T *eap) // Make 'cpoptions' empty, the 'l' flag should not be used here. char *const save_cpo = p_cpo; const bool save_cpo_allocated = is_option_allocated("cpo"); - p_cpo = empty_option; + p_cpo = empty_string_option; bool new_qi = false; if (is_loclist_cmd(eap->cmdidx)) { @@ -7232,7 +7232,7 @@ void ex_helpgrep(exarg_T *eap) updated = true; } - if (p_cpo == empty_option) { + if (p_cpo == empty_string_option) { p_cpo = save_cpo; } else { // Darn, some plugin changed the value. If it's still empty it was -- cgit From 5f03a1eaabfc8de2b3a9c666fcd604763f41e152 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 20 Oct 2023 15:10:33 +0200 Subject: build(lint): remove unnecessary clint.py rules Uncrustify is the source of truth where possible. Remove any redundant checks from clint.py. --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 5616a5a048..be2681e765 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1661,7 +1661,7 @@ static int qf_parse_multiline_pfx(int idx, qf_list_T *qfl, qffields_T *fields) } if (*fields->errmsg) { size_t textlen = strlen(qfprev->qf_text); - size_t errlen = strlen(fields->errmsg); + size_t errlen = strlen(fields->errmsg); qfprev->qf_text = xrealloc(qfprev->qf_text, textlen + errlen + 2); qfprev->qf_text[textlen] = '\n'; STRCPY(qfprev->qf_text + textlen + 1, fields->errmsg); -- cgit From f2fc44550fbe5b7ebfedc2b155dc41e93f49aedb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 26 Oct 2023 07:42:29 +0800 Subject: vim-patch:9.0.2064: cannot use buffer-number for errorformat (#25782) Problem: cannot use buffer-number for errorformat Solution: add support for parsing a buffer number using '%b' in 'errorformat' closes: vim/vim#13419 https://github.com/vim/vim/commit/b731800522af00fd348814d33a065b92e698afc3 Co-authored-by: Yegappan Lakshmanan --- src/nvim/quickfix.c | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index be2681e765..eae357ebf0 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -152,7 +152,7 @@ struct qf_info_S { static qf_info_T ql_info; // global quickfix list static unsigned last_qf_id = 0; // Last Used quickfix list id -#define FMT_PATTERNS 13 // maximum number of % recognized +#define FMT_PATTERNS 14 // maximum number of % recognized // Structure used to hold the info of one part of 'errorformat' typedef struct efm_S efm_T; @@ -217,6 +217,7 @@ typedef struct { typedef struct { char *namebuf; + int bnr; char *module; char *errmsg; size_t errmsglen; @@ -344,7 +345,7 @@ static int qf_init_process_nextline(qf_list_T *qfl, efm_T *fmt_first, qfstate_T : ((qfl->qf_currfile != NULL && fields->valid) ? qfl->qf_currfile : NULL), fields->module, - 0, + fields->bnr, fields->errmsg, fields->lnum, fields->end_lnum, @@ -391,20 +392,21 @@ static struct fmtpattern { char *pattern; } fmt_pat[FMT_PATTERNS] = { { 'f', ".\\+" }, // only used when at end - { 'n', "\\d\\+" }, // 1 - { 'l', "\\d\\+" }, // 2 - { 'e', "\\d\\+" }, // 3 - { 'c', "\\d\\+" }, // 4 - { 'k', "\\d\\+" }, // 5 - { 't', "." }, // 6 -#define FMT_PATTERN_M 7 - { 'm', ".\\+" }, // 7 -#define FMT_PATTERN_R 8 - { 'r', ".*" }, // 8 - { 'p', "[- \t.]*" }, // 9 - { 'v', "\\d\\+" }, // 10 - { 's', ".\\+" }, // 11 - { 'o', ".\\+" } // 12 + { 'b', "\\d\\+" }, // 1 + { 'n', "\\d\\+" }, // 2 + { 'l', "\\d\\+" }, // 3 + { 'e', "\\d\\+" }, // 4 + { 'c', "\\d\\+" }, // 5 + { 'k', "\\d\\+" }, // 6 + { 't', "." }, // 7 +#define FMT_PATTERN_M 8 + { 'm', ".\\+" }, // 8 +#define FMT_PATTERN_R 9 + { 'r', ".*" }, // 9 + { 'p', "[-\t .]*" }, // 10 + { 'v', "\\d\\+" }, // 11 + { 's', ".\\+" }, // 12 + { 'o', ".\\+" } // 13 }; /// Convert an errorformat pattern to a regular expression pattern. @@ -1312,6 +1314,21 @@ static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int pre return QF_OK; } +/// Parse the match for buffer number ('%b') pattern in regmatch. +/// Return the matched value in "fields->bnr". +static int qf_parse_fmt_b(regmatch_T *rmp, int midx, qffields_T *fields) +{ + if (rmp->startp[midx] == NULL) { + return QF_FAIL; + } + int bnr = (int)atol(rmp->startp[midx]); + if (buflist_findnr(bnr) == NULL) { + return QF_FAIL; + } + fields->bnr = bnr; + return QF_OK; +} + /// Parse the match for error number ('%n') pattern in regmatch. /// Return the matched value in "fields->enr". static int qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields) @@ -1496,6 +1513,7 @@ static int qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields) /// Keep in sync with fmt_pat[]. static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = { NULL, // %f + qf_parse_fmt_b, qf_parse_fmt_n, qf_parse_fmt_l, qf_parse_fmt_e, @@ -1568,6 +1586,7 @@ static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qf } fields->namebuf[0] = NUL; + fields->bnr = 0; fields->module[0] = NUL; fields->pattern[0] = NUL; if (!qf_multiscan) { -- cgit From acc646ad8fc3ef11fcc63b69f3d8484e4a91accd Mon Sep 17 00:00:00 2001 From: dundargoc Date: Fri, 29 Sep 2023 14:58:48 +0200 Subject: refactor: the long goodbye long is 32 bits on windows, while it is 64 bits on other architectures. This makes the type suboptimal for a codebase meant to be cross-platform. Replace it with more appropriate integer types. --- src/nvim/quickfix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index eae357ebf0..2e3cc4f170 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2084,7 +2084,7 @@ static int copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl) // Assign a new ID for the location list to_qfl->qf_id = ++last_qf_id; - to_qfl->qf_changedtick = 0L; + to_qfl->qf_changedtick = 0; // When no valid entries are present in the list, qf_ptr points to // the first item in the list @@ -3450,7 +3450,7 @@ static void qf_free(qf_list_T *qfl) qfl->qf_ctx = NULL; callback_free(&qfl->qf_qftf_cb); qfl->qf_id = 0; - qfl->qf_changedtick = 0L; + qfl->qf_changedtick = 0; } /// Adjust error list entries for changed line numbers -- cgit From 3d8f0cb695a5ea97ea05bc7decb19bb047cb753d Mon Sep 17 00:00:00 2001 From: voidiz <29259387+voidiz@users.noreply.github.com> Date: Wed, 8 Nov 2023 02:23:13 +0100 Subject: fix(diagnostic): check if delete failed in `qf_fill_buffer()` (#25932) When the contents of a quickfix buffer are replaced, there is a chance that deletion of the previous lines fails. This ensures that we don't get stuck in an infinite loop of retrying. Fix #25402 --- src/nvim/quickfix.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 2e3cc4f170..61157301b6 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4135,7 +4135,12 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // delete all existing lines while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) { - (void)ml_delete((linenr_T)1, false); + // If deletion fails, this loop may run forever, so + // signal error and return. + if (ml_delete((linenr_T)1, false) == FAIL) { + internal_error("qf_fill_buffer()"); + return; + } } } -- cgit From 8e58d37f2e15ac8540377148e55ed08a039aadb6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 11 Nov 2023 11:20:08 +0100 Subject: refactor: remove redundant casts --- src/nvim/quickfix.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 61157301b6..a9d048d998 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -380,7 +380,7 @@ int qf_init(win_T *wp, const char *restrict efile, char *restrict errorformat, i } return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, - newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); + newlist, 0, 0, qf_title, enc); } // Maximum number of bytes allowed per line while reading an errorfile. @@ -1605,7 +1605,7 @@ static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qf // Always ignore case when looking for a matching error. regmatch.rm_ic = true; regmatch.regprog = fmt_ptr->prog; - int r = vim_regexec(®match, linebuf, (colnr_T)0); + int r = vim_regexec(®match, linebuf, 0); fmt_ptr->prog = regmatch.regprog; int status = QF_FAIL; if (r) { @@ -2173,7 +2173,7 @@ static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname) xfree(ptr); } else { xfree(qf_last_bufname); - buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT); + buf = buflist_new(bufname, NULL, 0, BLN_NOOPT); qf_last_bufname = (bufname == ptr) ? bufname : xstrdup(bufname); set_bufref(&qf_last_bufref, buf); } @@ -2788,11 +2788,11 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int no_write_message(); return FAIL; } - retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1, + retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, 1, ECMD_HIDE + ECMD_SET_HELP, prev_winid == curwin->handle ? curwin : NULL); } else { - retval = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1, + retval = buflist_getfile(qf_ptr->qf_fnum, 1, GETF_SETMARK | GETF_SWITCH, forceit); } // If a location list, check whether the associated window is still @@ -4137,7 +4137,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) { // If deletion fails, this loop may run forever, so // signal error and return. - if (ml_delete((linenr_T)1, false) == FAIL) { + if (ml_delete(1, false) == FAIL) { internal_error("qf_fill_buffer()"); return; } @@ -5450,7 +5450,7 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo // ":lcd %:p:h" changes the meaning of short path names. os_dirname(dirname_start, MAXPATHL); - time_t seconds = (time_t)0; + time_t seconds = 0; for (int fi = 0; fi < cmd_args->fcount && !got_int && cmd_args->tomatch > 0; fi++) { char *fname = path_try_shorten_fname(cmd_args->fnames[fi]); if (time(NULL) > seconds) { @@ -5688,7 +5688,7 @@ static void restore_start_dir(char *dirname_start) static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resulting_dir) { // Allocate a buffer without putting it in the buffer list. - buf_T *newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); + buf_T *newbuf = buflist_new(NULL, NULL, 1, BLN_DUMMY); if (newbuf == NULL) { return NULL; } @@ -5720,7 +5720,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin bufref_T newbuf_to_wipe; newbuf_to_wipe.br_buf = NULL; - int readfile_result = readfile(fname, NULL, (linenr_T)0, (linenr_T)0, + int readfile_result = readfile(fname, NULL, 0, 0, (linenr_T)MAXLNUM, NULL, READ_NEW | READ_DUMMY, false); newbuf->b_locked--; @@ -5960,7 +5960,7 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL); if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, - true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) { + true, 0, 0, NULL, NULL) > 0) { (void)get_errorlist(qi, NULL, 0, 0, l); qf_free(&qi->qf_lists[0]); } @@ -6588,7 +6588,7 @@ static int qf_setprop_items_from_lines(qf_info_T *qi, int qf_idx, const dict_T * qf_free_items(&qi->qf_lists[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) { + false, 0, 0, NULL, NULL) >= 0) { retval = OK; } @@ -7051,7 +7051,7 @@ void ex_cexpr(exarg_T *eap) int res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm, (eap->cmdidx != CMD_caddexpr && eap->cmdidx != CMD_laddexpr), - (linenr_T)0, (linenr_T)0, + 0, 0, qf_cmdtitle(*eap->cmdlinep), NULL); if (qf_stack_empty(qi)) { decr_quickfix_busy(); @@ -7112,7 +7112,7 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch) while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) { char *line = IObuff; - if (vim_regexec(p_regmatch, line, (colnr_T)0)) { + if (vim_regexec(p_regmatch, line, 0)) { int l = (int)strlen(line); // remove trailing CR, LF, spaces, etc. -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/quickfix.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index a9d048d998..19b34b52b4 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // quickfix.c: functions for quickfix mode, using a file with error messages #include @@ -2812,8 +2809,8 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int return QF_ABORT; } - if (old_qf_curlist != qi->qf_curlist // -V560 - || old_changetick != qfl->qf_changedtick // -V560 + if (old_qf_curlist != qi->qf_curlist + || old_changetick != qfl->qf_changedtick || !is_qf_entry_present(qfl, qf_ptr)) { if (qfl_type == QFLT_QUICKFIX) { emsg(_(e_current_quickfix_list_was_changed)); @@ -2921,7 +2918,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int } } if (old_qf_curlist != qi->qf_curlist - || old_changetick != qfl->qf_changedtick // -V560 + || old_changetick != qfl->qf_changedtick || !is_qf_entry_present(qfl, qf_ptr)) { if (qfl_type == QFLT_QUICKFIX) { emsg(_(e_current_quickfix_list_was_changed)); -- cgit From a589156b4d3ea2dc72908b8773c42ad012929c64 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 17 Nov 2023 08:56:41 +0800 Subject: vim-patch:9.0.1857: [security] heap-use-after-free in is_qf_win() Problem: heap-use-after-free in is_qf_win() Solution: Check buffer is valid before accessing it https://github.com/vim/vim/commit/fc68299d436cf87453e432daa77b6d545df4d7ed Co-authored-by: Christian Brabandt --- src/nvim/quickfix.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 19b34b52b4..2ddee313a3 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -262,10 +262,8 @@ static const char *e_current_location_list_was_changed = #define IS_QF_LIST(qfl) ((qfl)->qfl_type == QFLT_QUICKFIX) #define IS_LL_LIST(qfl) ((qfl)->qfl_type == QFLT_LOCATION) -// // Return location list for window 'wp' // For location list window, return the referenced location list -// #define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? (wp)->w_llist_ref : (wp)->w_llist) // Macro to loop through all the items in a quickfix list @@ -3863,13 +3861,11 @@ static bool qf_win_pos_update(qf_info_T *qi, int old_qf_index) static int is_qf_win(const win_T *win, const qf_info_T *qi) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - // // A window displaying the quickfix buffer will have the w_llist_ref field // set to NULL. // A window displaying a location list buffer will have the w_llist_ref // pointing to the location list. - // - if (bt_quickfix(win->w_buffer)) { + if (buf_valid(win->w_buffer) && bt_quickfix(win->w_buffer)) { if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL) || (IS_LL_STACK(qi) && win->w_llist_ref == qi)) { return true; -- cgit From a6e3d93421ba13c407a96fac9cc01fa41ec7ad98 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 16 Nov 2023 10:59:11 +0100 Subject: refactor: enable formatting for ternaries This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators. --- src/nvim/quickfix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 2ddee313a3..57d3f2fd41 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -821,7 +821,7 @@ retry: } state->growbufsiz = (2 * state->growbufsiz < LINE_MAXLEN) - ? 2 * state->growbufsiz : LINE_MAXLEN; + ? 2 * state->growbufsiz : LINE_MAXLEN; state->growbuf = xrealloc(state->growbuf, state->growbufsiz); } @@ -858,7 +858,7 @@ retry: state->linebuf = line; state->growbuf = line; state->growbufsiz = state->linelen < LINE_MAXLEN - ? state->linelen : LINE_MAXLEN; + ? state->linelen : LINE_MAXLEN; } } } -- cgit From 8c6b0a5f21d5f0cf3781ef2b6fdbb306d5604a02 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 22 Nov 2023 11:07:00 +0800 Subject: vim-patch:9.0.2117: [security] use-after-free in qf_free_items (#26148) Problem: [security] use-after-free in qf_free_items Solution: only access qfpnext, if it hasn't been freed Coverity discovered a possible use-after-free in qf_free_items. When freeing the qfline items, we may access freed memory, when qfp == qfpnext. So only access qfpnext, when it hasn't been freed. https://github.com/vim/vim/commit/567cae2630a51efddc07eacff3b38a295e1f5671 Co-authored-by: Christian Brabandt --- src/nvim/quickfix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 57d3f2fd41..68217eefe7 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3411,9 +3411,10 @@ static void qf_free_items(qf_list_T *qfl) // to avoid crashing when it's wrong. // TODO(vim): Avoid qf_count being incorrect. qfl->qf_count = 1; + } else { + qfl->qf_start = qfpnext; } } - qfl->qf_start = qfpnext; qfl->qf_count--; } -- cgit From 38a20dd89f91c45ec8589bf1c50d50732882d38a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Nov 2023 20:58:37 +0800 Subject: build(IWYU): replace most private mappings with pragmas (#26247) --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 68217eefe7..fdc01e0a01 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -47,7 +47,7 @@ #include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/optionstr.h" -#include "nvim/os/fs_defs.h" +#include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/path.h" -- cgit From 8b428ca8b79ebb7b36c3e403ff3bcb6924a635a6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 16:00:21 +0100 Subject: build(IWYU): fix includes for func_attr.h --- src/nvim/quickfix.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index fdc01e0a01..c35e35916d 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -29,6 +29,7 @@ #include "nvim/ex_getln.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" -- cgit From f4aedbae4cb1f206f5b7c6142697b71dd473059b Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 18:39:38 +0100 Subject: build(IWYU): fix includes for undo_defs.h --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index c35e35916d..6076721d67 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -52,7 +52,7 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/path.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" #include "nvim/search.h" -- cgit From 6c14ae6bfaf51415b555e9a6b85d1d280976358d Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:27:32 +0100 Subject: refactor: rename types.h to types_defs.h --- src/nvim/quickfix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 6076721d67..6e4d6f39db 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -57,7 +57,7 @@ #include "nvim/regexp.h" #include "nvim/search.h" #include "nvim/strings.h" -#include "nvim/types.h" +#include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/vim.h" #include "nvim/window.h" -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/quickfix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 6e4d6f39db..eee0296ad6 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -11,7 +11,7 @@ #include #include "nvim/arglist.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/charset.h" @@ -36,7 +36,7 @@ #include "nvim/help.h" #include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mark.h" #include "nvim/mbyte.h" #include "nvim/memline.h" @@ -59,7 +59,7 @@ #include "nvim/strings.h" #include "nvim/types_defs.h" #include "nvim/ui.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" struct dir_stack_T { -- cgit From a6cba103cebce535279db197f9efeb34e9d1171f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 29 Nov 2023 20:32:40 +0800 Subject: refactor: move some constants out of vim_defs.h (#26298) --- src/nvim/quickfix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/nvim/quickfix.c') diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index eee0296ad6..4e20eb8925 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -34,7 +34,7 @@ #include "nvim/gettext.h" #include "nvim/globals.h" #include "nvim/help.h" -#include "nvim/highlight_defs.h" +#include "nvim/highlight.h" #include "nvim/highlight_group.h" #include "nvim/macros_defs.h" #include "nvim/mark.h" @@ -252,6 +252,8 @@ static const char *e_current_quickfix_list_was_changed = static const char *e_current_location_list_was_changed = N_("E926: Current location list was changed"); +enum { QF_WINHEIGHT = 10, }; ///< default height for quickfix window + // Quickfix window check helper macro #define IS_QF_WINDOW(wp) (bt_quickfix((wp)->w_buffer) && (wp)->w_llist_ref == NULL) // Location list window check helper macro -- cgit