aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/quickfix.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-01-25 18:31:31 +0000
commit9243becbedbb6a1592208051f8fa2b090dcc5e7d (patch)
tree607c2a862ec3f4399b8766383f6f8e04c4aa43b4 /src/nvim/quickfix.c
parent9e40b6e9e1bc67f2d856adb837ee64dd0e25b717 (diff)
parent3c48d3c83fc21dbc0841f9210f04bdb073d73cd1 (diff)
downloadrneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.gz
rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.tar.bz2
rneovim-9243becbedbb6a1592208051f8fa2b090dcc5e7d.zip
Merge remote-tracking branch 'upstream/master' into usermarksusermarks
Diffstat (limited to 'src/nvim/quickfix.c')
-rw-r--r--src/nvim/quickfix.c824
1 files changed, 452 insertions, 372 deletions
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 17fbbe17b8..5518fdfa51 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -4,30 +4,44 @@
// quickfix.c: functions for quickfix mode, using a file with error messages
#include <assert.h>
+#include <errno.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <time.h>
-#include "nvim/api/private/helpers.h"
#include "nvim/arglist.h"
#include "nvim/ascii.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/drawscreen.h"
#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"
+#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_eval.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/gettext.h"
+#include "nvim/globals.h"
#include "nvim/help.h"
+#include "nvim/highlight_defs.h"
#include "nvim/highlight_group.h"
+#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"
@@ -35,14 +49,16 @@
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/optionstr.h"
+#include "nvim/os/fs_defs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
-#include "nvim/os_unix.h"
#include "nvim/path.h"
+#include "nvim/pos.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/search.h"
#include "nvim/strings.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/vim.h"
#include "nvim/window.h"
@@ -67,9 +83,9 @@ struct qfline_S {
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
+ 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_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
};
@@ -100,7 +116,7 @@ typedef struct qf_list_S {
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
+ 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
@@ -176,6 +192,7 @@ enum {
QF_NOMEM = 3,
QF_IGNORE_LINE = 4,
QF_MULTISCAN = 5,
+ QF_ABORT = 6,
};
/// State information used to parse lines and add entries to a quickfix/location
@@ -336,8 +353,7 @@ static const size_t LINE_MAXLEN = 4096;
static struct fmtpattern {
char convchar;
char *pattern;
-} fmt_pat[FMT_PATTERNS] =
-{
+} fmt_pat[FMT_PATTERNS] = {
{ 'f', ".\\+" }, // only used when at end
{ 'n', "\\d\\+" }, // 1
{ 'l', "\\d\\+" }, // 2
@@ -368,9 +384,9 @@ static char *efmpat_to_regpat(const char *efmpat, char *regpat, efm_T *efminfo,
return NULL;
}
if ((idx && idx < FMT_PATTERN_R
- && vim_strchr("DXOPQ", efminfo->prefix) != NULL)
+ && vim_strchr("DXOPQ", (uint8_t)efminfo->prefix) != NULL)
|| (idx == FMT_PATTERN_R
- && vim_strchr("OPQ", efminfo->prefix) == NULL)) {
+ && vim_strchr("OPQ", (uint8_t)efminfo->prefix) == NULL)) {
semsg(_("E373: Unexpected %%%c in format string"), *efmpat);
return NULL;
}
@@ -452,10 +468,10 @@ static char *scanf_fmt_to_regpat(const char **pefmp, const char *efm, int len, c
static const char *efm_analyze_prefix(const char *efmp, efm_T *efminfo)
FUNC_ATTR_NONNULL_ALL
{
- if (vim_strchr("+-", *efmp) != NULL) {
+ if (vim_strchr("+-", (uint8_t)(*efmp)) != NULL) {
efminfo->flags = *efmp++;
}
- if (vim_strchr("DXAEWINCZGOPQ", *efmp) != NULL) {
+ if (vim_strchr("DXAEWINCZGOPQ", (uint8_t)(*efmp)) != NULL) {
efminfo->prefix = *efmp;
} else {
semsg(_("E376: Invalid %%%c in format string prefix"), *efmp);
@@ -494,7 +510,7 @@ static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat)
if (ptr == NULL) {
return FAIL;
}
- } else if (vim_strchr("%\\.^$~[", *efmp) != NULL) {
+ } else if (vim_strchr("%\\.^$~[", (uint8_t)(*efmp)) != NULL) {
*ptr++ = *efmp; // regexp magic characters
} else if (*efmp == '#') {
*ptr++ = '*';
@@ -514,7 +530,7 @@ static int efm_to_regpat(const char *efm, int len, efm_T *fmt_ptr, char *regpat)
} else { // copy normal character
if (*efmp == '\\' && efmp + 1 < efm + len) {
efmp++;
- } else if (vim_strchr(".*^$~[", *efmp) != NULL) {
+ } else if (vim_strchr(".*^$~[", (uint8_t)(*efmp)) != NULL) {
*ptr++ = '\\'; // escape regexp atoms
}
if (*efmp) {
@@ -548,9 +564,9 @@ static void free_efm_list(efm_T **efm_first)
/// a regular expression pattern.
static size_t efm_regpat_bufsz(char *efm)
{
- size_t sz = (FMT_PATTERNS * 3) + (STRLEN(efm) << 2);
+ size_t sz = (FMT_PATTERNS * 3) + (strlen(efm) << 2);
for (int i = FMT_PATTERNS - 1; i >= 0;) {
- sz += STRLEN(fmt_pat[i--].pattern);
+ sz += strlen(fmt_pat[i--].pattern);
}
#ifdef BACKSLASH_IN_FILENAME
sz += 12; // "%f" can become twelve chars longer (see efm_to_regpat)
@@ -562,7 +578,7 @@ static size_t efm_regpat_bufsz(char *efm)
}
/// Return the length of a 'errorformat' option part (separated by ",").
-static int efm_option_part_len(char *efm)
+static int efm_option_part_len(const char *efm)
{
int len;
@@ -607,7 +623,7 @@ static efm_T *parse_efm_option(char *efm)
goto parse_efm_error;
}
// Advance to next part
- efm = (char *)skip_to_option_part((char_u *)efm + len); // skip comma and spaces
+ efm = skip_to_option_part(efm + len); // skip comma and spaces
}
if (fmt_first == NULL) { // nothing found
@@ -652,12 +668,12 @@ static int qf_get_next_str_line(qfstate_T *state)
}
char *p = vim_strchr(p_str, '\n');
- size_t len = (p != NULL) ? (size_t)(p - p_str) + 1 : STRLEN(p_str);
+ size_t len = (p != NULL) ? (size_t)(p - p_str) + 1 : strlen(p_str);
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = (char *)IObuff;
+ state->linebuf = IObuff;
state->linelen = len;
}
memcpy(state->linebuf, p_str, state->linelen);
@@ -688,16 +704,16 @@ static int qf_get_next_list_line(qfstate_T *state)
return QF_END_OF_INPUT;
}
- size_t len = STRLEN(TV_LIST_ITEM_TV(p_li)->vval.v_string);
+ size_t len = strlen(TV_LIST_ITEM_TV(p_li)->vval.v_string);
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = (char *)IObuff;
+ state->linebuf = IObuff;
state->linelen = len;
}
- STRLCPY(state->linebuf, TV_LIST_ITEM_TV(p_li)->vval.v_string,
- state->linelen + 1);
+ xstrlcpy(state->linebuf, TV_LIST_ITEM_TV(p_li)->vval.v_string,
+ state->linelen + 1);
state->p_li = TV_LIST_ITEM_NEXT(state->p_list, p_li);
return QF_OK;
@@ -710,17 +726,17 @@ static int qf_get_next_buf_line(qfstate_T *state)
if (state->buflnum > state->lnumlast) {
return QF_END_OF_INPUT;
}
- char *p_buf = (char *)ml_get_buf(state->buf, state->buflnum, false);
+ char *p_buf = ml_get_buf(state->buf, state->buflnum, false);
state->buflnum += 1;
- size_t len = STRLEN(p_buf);
+ size_t len = strlen(p_buf);
if (len > IOSIZE - 2) {
state->linebuf = qf_grow_linebuf(state, len);
} else {
- state->linebuf = (char *)IObuff;
+ state->linebuf = IObuff;
state->linelen = len;
}
- STRLCPY(state->linebuf, p_buf, state->linelen + 1);
+ xstrlcpy(state->linebuf, p_buf, state->linelen + 1);
return QF_OK;
}
@@ -730,7 +746,7 @@ static int qf_get_next_file_line(qfstate_T *state)
{
retry:
errno = 0;
- if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
+ if (fgets(IObuff, IOSIZE, state->fd) == NULL) {
if (errno == EINTR) {
goto retry;
}
@@ -738,7 +754,7 @@ retry:
}
bool discard = false;
- state->linelen = STRLEN(IObuff);
+ state->linelen = strlen(IObuff);
if (state->linelen == IOSIZE - 1
&& !(IObuff[state->linelen - 1] == '\n')) {
// The current line exceeds IObuff, continue reading using growbuf
@@ -761,7 +777,7 @@ retry:
}
break;
}
- state->linelen = STRLEN(state->growbuf + growbuflen);
+ state->linelen = strlen(state->growbuf + growbuflen);
growbuflen += state->linelen;
if (state->growbuf[growbuflen - 1] == '\n') {
break;
@@ -780,13 +796,13 @@ retry:
// The current line is longer than LINE_MAXLEN, continue reading but
// discard everything until EOL or EOF is reached.
errno = 0;
- if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) {
+ if (fgets(IObuff, IOSIZE, state->fd) == NULL) {
if (errno == EINTR) {
continue;
}
break;
}
- if (STRLEN(IObuff) < IOSIZE - 1 || IObuff[IOSIZE - 2] == '\n') {
+ if (strlen(IObuff) < IOSIZE - 1 || IObuff[IOSIZE - 2] == '\n') {
break;
}
}
@@ -794,15 +810,15 @@ retry:
state->linebuf = state->growbuf;
state->linelen = growbuflen;
} else {
- state->linebuf = (char *)IObuff;
+ state->linebuf = IObuff;
}
// Convert a line if it contains a non-ASCII character
- if (state->vc.vc_type != CONV_NONE && has_non_ascii((char_u *)state->linebuf)) {
- char *line = (char *)string_convert(&state->vc, (char_u *)state->linebuf, &state->linelen);
+ if (state->vc.vc_type != CONV_NONE && has_non_ascii(state->linebuf)) {
+ char *line = string_convert(&state->vc, state->linebuf, &state->linelen);
if (line != NULL) {
if (state->linelen < IOSIZE) {
- STRLCPY(state->linebuf, line, state->linelen + 1);
+ xstrlcpy(state->linebuf, line, state->linelen + 1);
xfree(line);
} else {
xfree(state->growbuf);
@@ -852,7 +868,7 @@ static int qf_get_nextline(qfstate_T *state)
#endif
}
- remove_bom((char_u *)state->linebuf);
+ remove_bom(state->linebuf);
return QF_OK;
}
@@ -909,7 +925,7 @@ restofline:
// match or no match.
fields->valid = true;
for (; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) {
- idx = (char_u)fmt_ptr->prefix;
+ idx = (uint8_t)fmt_ptr->prefix;
status = qf_parse_get_fields(linebuf, linelen, fmt_ptr, fields,
qfl->qf_multiline, qfl->qf_multiscan,
&tail);
@@ -1000,7 +1016,7 @@ static int qf_setup_state(qfstate_T *pstate, char *restrict enc, const char *res
{
pstate->vc.vc_type = CONV_NONE;
if (enc != NULL && *enc != NUL) {
- convert_setup(&pstate->vc, (char_u *)enc, p_enc);
+ convert_setup(&pstate->vc, enc, p_enc);
}
if (efile != NULL
@@ -1058,6 +1074,7 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char *restrict efile, bu
{
qfstate_T state = { 0 };
qffields_T fields = { 0 };
+ qfline_T *old_last = NULL;
static efm_T *fmt_first = NULL;
static char *last_efm = NULL;
int retval = -1; // default: return error flag
@@ -1071,7 +1088,6 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char *restrict efile, bu
}
qf_list_T *qfl;
- qfline_T *old_last = NULL;
bool adding = false;
if (newlist || qf_idx == qi->qf_listcount) {
// make place for a new list
@@ -1091,14 +1107,14 @@ static int qf_init_ext(qf_info_T *qi, int qf_idx, const char *restrict efile, bu
// Use the local value of 'errorformat' if it's set.
if (errorformat == p_efm && tv == NULL && buf && *buf->b_p_efm != NUL) {
- efm = (char *)buf->b_p_efm;
+ efm = buf->b_p_efm;
} else {
efm = errorformat;
}
// If the errorformat didn't change between calls, then reuse the previously
// parsed values.
- if (last_efm == NULL || (STRCMP(last_efm, efm) != 0)) {
+ if (last_efm == NULL || (strcmp(last_efm, efm) != 0)) {
// free the previously parsed data
XFREE_CLEAR(last_efm);
free_efm_list(&fmt_first);
@@ -1174,13 +1190,15 @@ static void qf_store_title(qf_list_T *qfl, const char *title)
{
XFREE_CLEAR(qfl->qf_title);
- if (title != NULL) {
- size_t len = STRLEN(title) + 1;
- char *p = xmallocz(len);
-
- qfl->qf_title = p;
- STRLCPY(p, title, len + 1);
+ if (title == NULL) {
+ return;
}
+
+ size_t len = strlen(title) + 1;
+ char *p = xmallocz(len);
+
+ qfl->qf_title = p;
+ xstrlcpy(p, title, len + 1);
}
/// The title of a quickfix/location list is set, by default, to the command
@@ -1242,15 +1260,15 @@ static int qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int pre
}
// Expand ~/file and $HOME/file to full path.
- char c = (char)(*rmp->endp[midx]);
+ char c = *rmp->endp[midx];
*rmp->endp[midx] = NUL;
- expand_env(rmp->startp[midx], (char_u *)fields->namebuf, CMDBUFFSIZE);
- *rmp->endp[midx] = (char_u)c;
+ expand_env(rmp->startp[midx], fields->namebuf, CMDBUFFSIZE);
+ *rmp->endp[midx] = c;
// For separate filename patterns (%O, %P and %Q), the specified file
// should exist.
if (vim_strchr("OPQ", prefix) != NULL
- && !os_path_exists((char_u *)fields->namebuf)) {
+ && !os_path_exists(fields->namebuf)) {
return QF_FAIL;
}
@@ -1264,7 +1282,7 @@ static int qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->enr = (int)atol((char *)rmp->startp[midx]);
+ fields->enr = (int)atol(rmp->startp[midx]);
return QF_OK;
}
@@ -1275,7 +1293,7 @@ static int qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->lnum = (linenr_T)atol((char *)rmp->startp[midx]);
+ fields->lnum = (linenr_T)atol(rmp->startp[midx]);
return QF_OK;
}
@@ -1286,7 +1304,7 @@ static int qf_parse_fmt_e(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->end_lnum = (linenr_T)atol((char *)rmp->startp[midx]);
+ fields->end_lnum = (linenr_T)atol(rmp->startp[midx]);
return QF_OK;
}
@@ -1297,7 +1315,7 @@ static int qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->col = (int)atol((char *)rmp->startp[midx]);
+ fields->col = (int)atol(rmp->startp[midx]);
return QF_OK;
}
@@ -1308,7 +1326,7 @@ static int qf_parse_fmt_k(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->end_col = (int)atol((char *)rmp->startp[midx]);
+ fields->end_col = (int)atol(rmp->startp[midx]);
return QF_OK;
}
@@ -1319,13 +1337,13 @@ static int qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->type = (char)(*rmp->startp[midx]);
+ fields->type = *rmp->startp[midx];
return QF_OK;
}
-/// Parse the match for '%+' format pattern. The whole matching line is included
-/// in the error string. Return the matched line in "fields->errmsg".
-static void qf_parse_fmt_plus(const char *linebuf, size_t linelen, qffields_T *fields)
+/// Copy a non-error line into the error string. Return the matched line in
+/// "fields->errmsg".
+static int copy_nonerror_line(const char *linebuf, size_t linelen, qffields_T *fields)
FUNC_ATTR_NONNULL_ALL
{
if (linelen >= fields->errmsglen) {
@@ -1333,7 +1351,10 @@ static void qf_parse_fmt_plus(const char *linebuf, size_t linelen, qffields_T *f
fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
fields->errmsglen = linelen + 1;
}
- STRLCPY(fields->errmsg, linebuf, linelen + 1);
+ // copy whole line to error message
+ xstrlcpy(fields->errmsg, linebuf, linelen + 1);
+
+ return QF_OK;
}
/// Parse the match for error message ('%m') pattern in regmatch.
@@ -1349,7 +1370,7 @@ static int qf_parse_fmt_m(regmatch_T *rmp, int midx, qffields_T *fields)
fields->errmsg = xrealloc(fields->errmsg, len + 1);
fields->errmsglen = len + 1;
}
- STRLCPY(fields->errmsg, rmp->startp[midx], len + 1);
+ xstrlcpy(fields->errmsg, rmp->startp[midx], len + 1);
return QF_OK;
}
@@ -1360,7 +1381,7 @@ static int qf_parse_fmt_r(regmatch_T *rmp, int midx, char **tail)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- *tail = (char *)rmp->startp[midx];
+ *tail = rmp->startp[midx];
return QF_OK;
}
@@ -1372,7 +1393,7 @@ static int qf_parse_fmt_p(regmatch_T *rmp, int midx, qffields_T *fields)
return QF_FAIL;
}
fields->col = 0;
- for (char *match_ptr = (char *)rmp->startp[midx]; (char_u *)match_ptr != rmp->endp[midx];
+ for (char *match_ptr = rmp->startp[midx]; match_ptr != rmp->endp[midx];
match_ptr++) {
fields->col++;
if (*match_ptr == TAB) {
@@ -1392,7 +1413,7 @@ static int qf_parse_fmt_v(regmatch_T *rmp, int midx, qffields_T *fields)
if (rmp->startp[midx] == NULL) {
return QF_FAIL;
}
- fields->col = (int)atol((char *)rmp->startp[midx]);
+ fields->col = (int)atol(rmp->startp[midx]);
fields->use_viscol = true;
return QF_OK;
}
@@ -1409,7 +1430,7 @@ static int qf_parse_fmt_s(regmatch_T *rmp, int midx, qffields_T *fields)
len = CMDBUFFSIZE - 5;
}
STRCPY(fields->pattern, "^\\V");
- STRLCAT(fields->pattern, rmp->startp[midx], len + 4);
+ xstrlcat(fields->pattern, rmp->startp[midx], len + 4);
fields->pattern[len + 3] = '\\';
fields->pattern[len + 4] = '$';
fields->pattern[len + 5] = NUL;
@@ -1424,11 +1445,11 @@ static int qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
return QF_FAIL;
}
size_t len = (size_t)(rmp->endp[midx] - rmp->startp[midx]);
- size_t dsize = STRLEN(fields->module) + len + 1;
+ size_t dsize = strlen(fields->module) + len + 1;
if (dsize > CMDBUFFSIZE) {
dsize = CMDBUFFSIZE;
}
- STRLCAT(fields->module, rmp->startp[midx], dsize);
+ xstrlcat(fields->module, rmp->startp[midx], dsize);
return QF_OK;
}
@@ -1464,7 +1485,7 @@ static int qf_parse_match(char *linebuf, size_t linelen, efm_T *fmt_ptr, regmatc
if ((idx == 'C' || idx == 'Z') && !qf_multiline) {
return QF_FAIL;
}
- if (vim_strchr("EWIN", idx) != NULL) {
+ if (vim_strchr("EWIN", (uint8_t)idx) != NULL) {
fields->type = idx;
} else {
fields->type = 0;
@@ -1480,7 +1501,7 @@ static int qf_parse_match(char *linebuf, size_t linelen, efm_T *fmt_ptr, regmatc
status = qf_parse_fmt_f(regmatch, midx, fields, idx);
} else if (i == FMT_PATTERN_M) {
if (fmt_ptr->flags == '+' && !qf_multiscan) { // %+
- qf_parse_fmt_plus(linebuf, linelen, fields);
+ status = copy_nonerror_line(linebuf, linelen, fields);
} else if (midx > 0) { // %m
status = qf_parse_fmt_m(regmatch, midx, fields);
}
@@ -1505,7 +1526,7 @@ static int qf_parse_match(char *linebuf, size_t linelen, efm_T *fmt_ptr, regmatc
static int qf_parse_get_fields(char *linebuf, size_t linelen, efm_T *fmt_ptr, qffields_T *fields,
int qf_multiline, int qf_multiscan, char **tail)
{
- if (qf_multiscan && vim_strchr("OPQ", fmt_ptr->prefix) == NULL) {
+ if (qf_multiscan && vim_strchr("OPQ", (uint8_t)fmt_ptr->prefix) == NULL) {
return QF_FAIL;
}
@@ -1564,7 +1585,7 @@ static int qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl)
static int qf_parse_file_pfx(int idx, qffields_T *fields, qf_list_T *qfl, char *tail)
{
fields->valid = false;
- if (*fields->namebuf == NUL || os_path_exists((char_u *)fields->namebuf)) {
+ if (*fields->namebuf == NUL || os_path_exists(fields->namebuf)) {
if (*fields->namebuf && idx == 'P') {
qfl->qf_currfile = qf_push_dir(fields->namebuf, &qfl->qf_file_stack, true);
} else if (idx == 'Q') {
@@ -1588,15 +1609,8 @@ static int qf_parse_line_nomatch(char *linebuf, size_t linelen, qffields_T *fiel
fields->namebuf[0] = NUL; // no match found, remove file name
fields->lnum = 0; // don't jump to this line
fields->valid = false;
- if (linelen >= fields->errmsglen) {
- // linelen + null terminator
- fields->errmsg = xrealloc(fields->errmsg, linelen + 1);
- fields->errmsglen = linelen + 1;
- }
- // copy whole line to error message
- STRLCPY(fields->errmsg, linebuf, linelen + 1);
- return QF_OK;
+ return copy_nonerror_line(linebuf, linelen, fields);
}
/// Parse multi-line error format prefixes (%C and %Z)
@@ -1609,8 +1623,8 @@ static int qf_parse_multiline_pfx(int idx, qf_list_T *qfl, qffields_T *fields)
return QF_FAIL;
}
if (*fields->errmsg) {
- size_t textlen = STRLEN(qfprev->qf_text);
- size_t errlen = STRLEN(fields->errmsg);
+ size_t textlen = strlen(qfprev->qf_text);
+ 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);
@@ -1672,14 +1686,16 @@ int qf_stack_get_bufnr(void)
static void wipe_qf_buffer(qf_info_T *qi)
FUNC_ATTR_NONNULL_ALL
{
- if (qi->qf_bufnr != INVALID_QFBUFNR) {
- buf_T *const qfbuf = buflist_findnr(qi->qf_bufnr);
- if (qfbuf != NULL && qfbuf->b_nwindows == 0) {
- // If the quickfix buffer is not loaded in any window, then
- // wipe the buffer.
- close_buffer(NULL, qfbuf, DOBUF_WIPE, false, false);
- qi->qf_bufnr = INVALID_QFBUFNR;
- }
+ if (qi->qf_bufnr == INVALID_QFBUFNR) {
+ return;
+ }
+
+ buf_T *const qfbuf = buflist_findnr(qi->qf_bufnr);
+ if (qfbuf != NULL && qfbuf->b_nwindows == 0) {
+ // If the quickfix buffer is not loaded in any window, then
+ // wipe the buffer.
+ close_buffer(NULL, qfbuf, DOBUF_WIPE, false, false);
+ qi->qf_bufnr = INVALID_QFBUFNR;
}
}
@@ -1790,7 +1806,7 @@ void check_quickfix_busy(void)
/// @param type type character
/// @param valid valid entry
///
-/// @returns QF_OK or QF_FAIL.
+/// @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)
@@ -1891,7 +1907,7 @@ static qf_info_T *ll_get_or_alloc_list(win_T *wp)
/// Get the quickfix/location list stack to use for the specified Ex command.
/// For a location list command, returns the stack for the current window. If
/// the location list is not found, then returns NULL and prints an error
-/// message if 'print_emsg' is TRUE.
+/// message if 'print_emsg' is true.
static qf_info_T *qf_cmd_get_stack(exarg_T *eap, int print_emsg)
{
qf_info_T *qi = &ql_info;
@@ -2063,13 +2079,13 @@ static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname)
}
slash_adjust(fname);
#endif
- if (directory != NULL && !vim_isAbsName((char_u *)fname)) {
+ if (directory != NULL && !vim_isAbsName(fname)) {
ptr = concat_fnames(directory, fname, true);
// Here we check if the file really exists.
// This should normally be true, but if make works without
// "leaving directory"-messages we might have missed a
// directory change.
- if (!os_path_exists((char_u *)ptr)) {
+ if (!os_path_exists(ptr)) {
xfree(ptr);
directory = qf_guess_filepath(qfl, fname);
if (directory) {
@@ -2085,7 +2101,7 @@ static int qf_get_fnum(qf_list_T *qfl, char *directory, char *fname)
}
if (qf_last_bufname != NULL
- && STRCMP(bufname, qf_last_bufname) == 0
+ && strcmp(bufname, qf_last_bufname) == 0
&& bufref_valid(&qf_last_bufref)) {
buf = qf_last_bufref.br_buf;
xfree(ptr);
@@ -2116,7 +2132,7 @@ static char *qf_push_dir(char *dirbuf, struct dir_stack_T **stackptr, bool is_fi
*stackptr = ds_new;
// store directory on the stack
- if (vim_isAbsName((char_u *)dirbuf)
+ if (vim_isAbsName(dirbuf)
|| (*stackptr)->next == NULL
|| is_file_stack) {
(*stackptr)->dirname = xstrdup(dirbuf);
@@ -2129,7 +2145,7 @@ static char *qf_push_dir(char *dirbuf, struct dir_stack_T **stackptr, bool is_fi
while (ds_new) {
xfree((*stackptr)->dirname);
(*stackptr)->dirname = concat_fnames(ds_new->dirname, dirbuf, true);
- if (os_isdir((char_u *)(*stackptr)->dirname)) {
+ if (os_isdir((*stackptr)->dirname)) {
break;
}
@@ -2153,12 +2169,11 @@ static char *qf_push_dir(char *dirbuf, struct dir_stack_T **stackptr, bool is_fi
if ((*stackptr)->dirname != NULL) {
return (*stackptr)->dirname;
- } else {
- ds_ptr = *stackptr;
- *stackptr = (*stackptr)->next;
- xfree(ds_ptr);
- return NULL;
}
+ ds_ptr = *stackptr;
+ *stackptr = (*stackptr)->next;
+ xfree(ds_ptr);
+ return NULL;
}
// pop dirbuf from the directory stack and return previous directory or NULL if
@@ -2223,7 +2238,7 @@ static char *qf_guess_filepath(qf_list_T *qfl, char *filename)
xfree(fullname);
fullname = concat_fnames(ds_ptr->dirname, filename, true);
- if (os_path_exists((char_u *)fullname)) {
+ if (os_path_exists(fullname)) {
break;
}
@@ -2511,7 +2526,7 @@ static win_T *qf_find_win_with_normal_buf(void)
}
// Go to a window in any tabpage containing the specified file. Returns true
-// if successfully jumped to the window. Otherwise returns FALSE.
+// if successfully jumped to the window. Otherwise returns false.
static bool qf_goto_tabwin_with_file(int fnum)
{
FOR_ALL_TAB_WINDOWS(tp, wp) {
@@ -2686,6 +2701,10 @@ static int qf_jump_to_usable_window(int qf_fnum, bool newwin, int *opened_window
}
/// Edit the selected file or help file.
+/// @return OK if successfully edited the file.
+/// FAIL on failing to open the buffer.
+/// QF_ABORT if the quickfix/location list was freed by an autocmd
+/// when opening the buffer.
static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int prev_winid,
int *opened_window)
{
@@ -2702,11 +2721,10 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int
if (!can_abandon(curbuf, forceit)) {
no_write_message();
return FAIL;
- } else {
- retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
- ECMD_HIDE + ECMD_SET_HELP,
- prev_winid == curwin->handle ? curwin : NULL);
}
+ retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
+ ECMD_HIDE + ECMD_SET_HELP,
+ prev_winid == curwin->handle ? curwin : NULL);
} else {
retval = buflist_getfile(qf_ptr->qf_fnum, (linenr_T)1,
GETF_SETMARK | GETF_SWITCH, forceit);
@@ -2719,13 +2737,13 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int
if (wp == NULL && curwin->w_llist != qi) {
emsg(_("E924: Current window was closed"));
*opened_window = false;
- return NOTDONE;
+ return QF_ABORT;
}
}
if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) {
emsg(_(e_current_quickfix_list_was_changed));
- return NOTDONE;
+ return QF_ABORT;
}
if (old_qf_curlist != qi->qf_curlist // -V560
@@ -2736,7 +2754,7 @@ static int qf_jump_edit_buffer(qf_info_T *qi, qfline_T *qf_ptr, int forceit, int
} else {
emsg(_(e_current_location_list_was_changed));
}
- return NOTDONE;
+ return QF_ABORT;
}
return retval;
@@ -2771,7 +2789,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, '/', '/', (char_u *)qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
+ if (!do_search(NULL, '/', '/', qf_pattern, (long)1, SEARCH_KEEP, NULL)) {
curwin->w_cursor = save_cursor;
}
}
@@ -2784,15 +2802,18 @@ static void qf_jump_print_msg(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, buf
// Update the screen before showing the message, unless the screen
// scrolled up.
if (!msg_scrolled) {
- update_topline_redraw();
+ update_topline(curwin);
+ if (must_redraw) {
+ update_screen();
+ }
}
- snprintf((char *)IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index,
+ 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), (char *)IObuff + len, IOSIZE - len);
+ int len = (int)strlen(IObuff);
+ qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
// Output the message. Overwrite to avoid scrolling when the 'O'
// flag is present in 'shortmess'; But when not jumping, print the
@@ -2804,16 +2825,17 @@ 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((char *)IObuff, 0, true, false);
+ msg_attr_keep(IObuff, 0, true, false);
msg_scroll = (int)i;
}
/// Find a usable window for opening a file from the quickfix/location list. If
/// a window is not found then open a new window. If 'newwin' is true, then open
/// a new window.
-/// Returns OK if successfully jumped or opened a window. Returns FAIL if not
-/// able to jump/open a window. Returns NOTDONE if a file is not associated
-/// with the entry.
+/// @return OK if successfully jumped or opened a window.
+/// FAIL if not able to jump/open a window.
+/// NOTDONE if a file is not associated with the entry.
+/// QF_ABORT if the quickfix/location list was modified by an autocmd.
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);
@@ -2835,7 +2857,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int
} else {
emsg(_(e_current_location_list_was_changed));
}
- return FAIL;
+ return QF_ABORT;
}
// If currently in the quickfix window, find another window to show the
@@ -2860,7 +2882,7 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int
} else {
emsg(_(e_current_location_list_was_changed));
}
- return FAIL;
+ return QF_ABORT;
}
return OK;
@@ -2869,9 +2891,9 @@ static int qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, bool newwin, int
/// Edit a selected file from the quickfix/location list and jump to a
/// particular line/column, adjust the folds and display a message about the
/// jump.
-/// Returns OK on success and FAIL on failing to open the file/buffer. Returns
-/// NOTDONE if the quickfix/location list is freed by an autocmd when opening
-/// the file.
+/// @return OK on success and FAIL on failing to open the file/buffer.
+/// QF_ABORT if the quickfix/location list is freed by an autocmd when opening
+/// the file.
static int qf_jump_to_buffer(qf_info_T *qi, int qf_index, qfline_T *qf_ptr, int forceit,
int prev_winid, int *opened_window, int openfold, int print_message)
{
@@ -2923,7 +2945,7 @@ void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit)
// If 'newwin' is true, then open the file in a new window.
static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, bool newwin)
{
- char *old_swb = (char *)p_swb;
+ char *old_swb = p_swb;
unsigned old_swb_flags = swb_flags;
const bool old_KeyTyped = KeyTyped; // getting file may reset it
@@ -2932,7 +2954,7 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
}
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
- emsg(_(e_quickfix));
+ emsg(_(e_no_errors));
return;
}
@@ -2965,14 +2987,19 @@ static void qf_jump_newwin(qf_info_T *qi, int dir, int errornr, int forceit, boo
if (retval == FAIL) {
goto failed;
}
+ if (retval == QF_ABORT) {
+ qi = NULL;
+ qf_ptr = NULL;
+ goto theend;
+ }
if (retval == NOTDONE) {
goto theend;
}
retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid,
&opened_window, old_KeyTyped, print_message);
- if (retval == NOTDONE) {
- // Quickfix/location list is freed by an autocmd
+ if (retval == QF_ABORT) {
+ // Quickfix/location list was modified by an autocmd
qi = NULL;
qf_ptr = NULL;
}
@@ -2994,10 +3021,10 @@ theend:
qfl->qf_ptr = qf_ptr;
qfl->qf_index = qf_index;
}
- if (p_swb != (char_u *)old_swb && p_swb == empty_option) {
+ if (p_swb != old_swb && p_swb == empty_option) {
// Restore old 'switchbuf' value, but not when an autocommand or
// modeline has changed the value.
- p_swb = (char_u *)old_swb;
+ p_swb = old_swb;
swb_flags = old_swb_flags;
}
decr_quickfix_busy();
@@ -3016,7 +3043,7 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
{
char *fname = NULL;
if (qfp->qf_module != NULL && *qfp->qf_module != NUL) {
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx, qfp->qf_module);
+ vim_snprintf(IObuff, IOSIZE, "%2d %s", qf_idx, qfp->qf_module);
} else {
buf_T *buf;
if (qfp->qf_fnum != 0
@@ -3027,9 +3054,9 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
}
}
if (fname == NULL) {
- snprintf((char *)IObuff, IOSIZE, "%2d", qf_idx);
+ snprintf(IObuff, IOSIZE, "%2d", qf_idx);
} else {
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx, fname);
+ vim_snprintf(IObuff, IOSIZE, "%2d %s", qf_idx, fname);
}
}
@@ -3038,16 +3065,16 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
// text of the entry.
bool filter_entry = true;
if (qfp->qf_module != NULL && *qfp->qf_module != NUL) {
- filter_entry &= message_filtered((char_u *)qfp->qf_module);
+ filter_entry &= message_filtered(qfp->qf_module);
}
if (filter_entry && fname != NULL) {
- filter_entry &= message_filtered((char_u *)fname);
+ filter_entry &= message_filtered(fname);
}
if (filter_entry && qfp->qf_pattern != NULL) {
- filter_entry &= message_filtered((char_u *)qfp->qf_pattern);
+ filter_entry &= message_filtered(qfp->qf_pattern);
}
if (filter_entry) {
- filter_entry &= message_filtered((char_u *)qfp->qf_text);
+ filter_entry &= message_filtered(qfp->qf_text);
}
if (filter_entry) {
return;
@@ -3062,21 +3089,21 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
if (qfp->qf_lnum == 0) {
IObuff[0] = NUL;
} else {
- qf_range_text(qfp, (char *)IObuff, IOSIZE);
+ qf_range_text(qfp, IObuff, IOSIZE);
}
- vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s", qf_types(qfp->qf_type, qfp->qf_nr));
+ vim_snprintf(IObuff + strlen(IObuff), IOSIZE, "%s", qf_types(qfp->qf_type, qfp->qf_nr));
msg_puts_attr((const char *)IObuff, qfLineAttr);
msg_puts_attr(":", qfSepAttr);
if (qfp->qf_pattern != NULL) {
- qf_fmt_text(qfp->qf_pattern, (char *)IObuff, IOSIZE);
+ qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
msg_puts((const char *)IObuff);
msg_puts_attr(":", qfSepAttr);
}
msg_puts(" ");
- char_u *tbuf = IObuff;
+ char *tbuf = IObuff;
size_t tbuflen = IOSIZE;
- size_t len = STRLEN(qfp->qf_text) + 3;
+ size_t len = strlen(qfp->qf_text) + 3;
if (len > IOSIZE) {
tbuf = xmalloc(len);
@@ -3088,14 +3115,12 @@ static void qf_list_entry(qfline_T *qfp, int qf_idx, bool cursel)
// with ^^^^.
qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
? skipwhite(qfp->qf_text) : qfp->qf_text,
- (char *)tbuf, (int)tbuflen);
+ tbuf, (int)tbuflen);
msg_prt_line(tbuf, false);
if (tbuf != IObuff) {
xfree(tbuf);
}
-
- ui_flush(); // show one line at a time
}
// ":clist": list all errors
@@ -3111,7 +3136,7 @@ void qf_list(exarg_T *eap)
}
if (qf_stack_empty(qi) || qf_list_empty(qf_get_curlist(qi))) {
- emsg(_(e_quickfix));
+ emsg(_(e_no_errors));
return;
}
@@ -3147,15 +3172,15 @@ void qf_list(exarg_T *eap)
// Get the attributes for the different quickfix highlight items. Note
// that this depends on syntax items defined in the qf.vim syntax file
- qfFileAttr = syn_name2attr((char_u *)"qfFileName");
+ qfFileAttr = syn_name2attr("qfFileName");
if (qfFileAttr == 0) {
qfFileAttr = HL_ATTR(HLF_D);
}
- qfSepAttr = syn_name2attr((char_u *)"qfSeparator");
+ qfSepAttr = syn_name2attr("qfSeparator");
if (qfSepAttr == 0) {
qfSepAttr = HL_ATTR(HLF_D);
}
- qfLineAttr = syn_name2attr((char_u *)"qfLineNr");
+ qfLineAttr = syn_name2attr("qfLineNr");
if (qfLineAttr == 0) {
qfLineAttr = HL_ATTR(HLF_N);
}
@@ -3180,7 +3205,7 @@ static void qf_fmt_text(const char *restrict text, char *restrict buf, int bufsi
int i;
const char *p = (char *)text;
- for (i = 0; *p != NUL && i < bufsize - 1; ++i) {
+ for (i = 0; *p != NUL && i < bufsize - 1; i++) {
if (*p == '\n') {
buf[i] = ' ';
while (*++p != NUL) {
@@ -3200,18 +3225,18 @@ static void qf_fmt_text(const char *restrict text, char *restrict buf, int bufsi
static void qf_range_text(const qfline_T *qfp, char *buf, int bufsize)
{
vim_snprintf(buf, (size_t)bufsize, "%" PRIdLINENR, qfp->qf_lnum);
- int len = (int)STRLEN(buf);
+ int len = (int)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);
+ len += (int)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);
+ len += (int)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);
+ len += (int)strlen(buf + len);
}
}
buf[len] = NUL;
@@ -3232,13 +3257,13 @@ static void qf_msg(qf_info_T *qi, int which, char *lead)
count);
if (title != NULL) {
- size_t len = STRLEN(buf);
+ size_t len = strlen(buf);
if (len < 34) {
memset(buf + len, ' ', 34 - len);
buf[34] = NUL;
}
- STRLCAT(buf, title, IOSIZE);
+ xstrlcat(buf, title, IOSIZE);
}
trunc_string(buf, buf, Columns - 1, IOSIZE);
msg(buf);
@@ -3263,13 +3288,13 @@ void qf_age(exarg_T *eap)
emsg(_("E380: At bottom of quickfix stack"));
break;
}
- --qi->qf_curlist;
+ qi->qf_curlist--;
} else {
if (qi->qf_curlist >= qi->qf_listcount - 1) {
emsg(_("E381: At top of quickfix stack"));
break;
}
- ++qi->qf_curlist;
+ qi->qf_curlist++;
}
}
qf_msg(qi, qi->qf_curlist, "");
@@ -3393,7 +3418,7 @@ bool qf_mark_adjust(win_T *wp, linenr_T line1, linenr_T line2, linenr_T amount,
found_one = true;
if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) {
if (amount == MAXLNUM) {
- qfp->qf_cleared = TRUE;
+ qfp->qf_cleared = true;
} else {
qfp->qf_lnum += amount;
}
@@ -3460,14 +3485,12 @@ void qf_view_result(bool split)
{
qf_info_T *qi = &ql_info;
- if (!bt_quickfix(curbuf)) {
- return;
- }
if (IS_LL_WINDOW(curwin)) {
qi = GET_LOC_LIST(curwin);
}
+
if (qf_list_empty(qf_get_curlist(qi))) {
- emsg(_(e_quickfix));
+ emsg(_(e_no_errors));
return;
}
@@ -3558,12 +3581,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("swf", 0L, NULL, OPT_LOCAL);
- set_option_value("bt", 0L, "quickfix", OPT_LOCAL);
- set_option_value("bh", 0L, "hide", OPT_LOCAL);
+ 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);
RESET_BINDING(curwin);
curwin->w_p_diff = false;
- set_option_value("fdm", 0L, "manual", OPT_LOCAL);
+ set_option_value_give_err("fdm", 0L, "manual", OPT_LOCAL);
}
// Open a new quickfix or location list window, load the quickfix buffer and
@@ -3710,7 +3733,7 @@ static void qf_win_goto(win_T *win, linenr_T lnum)
curwin->w_cursor.coladd = 0;
curwin->w_curswant = 0;
update_topline(curwin); // scroll to show the line
- redraw_later(curwin, VALID);
+ redraw_later(curwin, UPD_VALID);
curwin->w_redr_status = true; // update ruler
curwin = old_curwin;
curbuf = curwin->w_buffer;
@@ -3747,7 +3770,7 @@ linenr_T qf_current_entry(win_T *wp)
}
/// Update the cursor position in the quickfix window to the current error.
-/// Return TRUE if there is a quickfix window.
+/// Return true if there is a quickfix window.
///
/// @param old_qf_index previous qf_index or zero
static bool qf_win_pos_update(qf_info_T *qi, int old_qf_index)
@@ -3831,10 +3854,11 @@ static buf_T *qf_find_buf(qf_info_T *qi)
}
/// Process the 'quickfixtextfunc' option value.
-/// @return OK or FAIL
-int qf_process_qftf_option(void)
+void qf_process_qftf_option(char **errmsg)
{
- return option_set_callback_func(p_qftf, &qftf_cb);
+ if (option_set_callback_func(p_qftf, &qftf_cb) == FAIL) {
+ *errmsg = e_invarg;
+ }
}
/// Update the w:quickfix_title variable in the quickfix/location list window in
@@ -3859,48 +3883,61 @@ static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last)
{
// Check if a buffer for the quickfix list exists. Update it.
buf_T *buf = qf_find_buf(qi);
- if (buf != NULL) {
- linenr_T old_line_count = buf->b_ml.ml_line_count;
- int qf_winid = 0;
-
- win_T *win;
- if (IS_LL_STACK(qi)) {
- if (curwin->w_llist == qi) {
- win = curwin;
- } else {
- win = qf_find_win_with_loclist(qi);
- if (win == NULL) {
- return;
- }
+ if (buf == NULL) {
+ return;
+ }
+
+ linenr_T old_line_count = buf->b_ml.ml_line_count;
+ int qf_winid = 0;
+
+ win_T *win;
+ if (IS_LL_STACK(qi)) {
+ if (curwin->w_llist == qi) {
+ win = curwin;
+ } else {
+ // Find the file window (non-quickfix) with this location list
+ win = qf_find_win_with_loclist(qi);
+ if (win == NULL) {
+ // File window is not found. Find the location list window.
+ win = qf_find_win(qi);
+ }
+ if (win == NULL) {
+ return;
}
- qf_winid = (int)win->handle;
}
+ qf_winid = (int)win->handle;
+ }
- aco_save_T aco;
+ // autocommands may cause trouble
+ incr_quickfix_busy();
- if (old_last == NULL) {
- // set curwin/curbuf to buf and save a few things
- aucmd_prepbuf(&aco, buf);
- }
+ aco_save_T aco;
- qf_update_win_titlevar(qi);
+ if (old_last == NULL) {
+ // set curwin/curbuf to buf and save a few things
+ aucmd_prepbuf(&aco, buf);
+ }
- qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
- buf_inc_changedtick(buf);
+ qf_update_win_titlevar(qi);
- if (old_last == NULL) {
- (void)qf_win_pos_update(qi, 0);
+ qf_fill_buffer(qf_get_curlist(qi), buf, old_last, qf_winid);
+ buf_inc_changedtick(buf);
- // restore curwin/curbuf and a few other things
- aucmd_restbuf(&aco);
- }
+ if (old_last == NULL) {
+ (void)qf_win_pos_update(qi, 0);
- // Only redraw when added lines are visible. This avoids flickering when
- // the added lines are not visible.
- if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) {
- redraw_buf_later(buf, NOT_VALID);
- }
+ // restore curwin/curbuf and a few other things
+ aucmd_restbuf(&aco);
}
+
+ // Only redraw when added lines are visible. This avoids flickering when
+ // the added lines are not visible.
+ if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) {
+ redraw_buf_later(buf, UPD_NOT_VALID);
+ }
+
+ // always called after incr_quickfix_busy()
+ decr_quickfix_busy();
}
// Add an error line to the quickfix buffer.
@@ -3911,33 +3948,33 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
// If the 'quickfixtextfunc' function returned a non-empty custom string
// for this entry, then use it.
if (qftf_str != NULL && *qftf_str != NUL) {
- STRLCPY(IObuff, qftf_str, IOSIZE);
+ xstrlcpy(IObuff, qftf_str, IOSIZE);
} else {
buf_T *errbuf;
int len;
if (qfp->qf_module != NULL) {
- STRLCPY(IObuff, qfp->qf_module, IOSIZE);
- len = (int)STRLEN(IObuff);
+ xstrlcpy(IObuff, qfp->qf_module, IOSIZE);
+ len = (int)strlen(IObuff);
} else if (qfp->qf_fnum != 0
&& (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL
&& errbuf->b_fname != NULL) {
if (qfp->qf_type == 1) { // :helpgrep
- STRLCPY(IObuff, path_tail(errbuf->b_fname), IOSIZE);
+ xstrlcpy(IObuff, path_tail(errbuf->b_fname), IOSIZE);
} else {
// Shorten the file name if not done already.
// For optimization, do this only for the first entry in a
// buffer.
if (first_bufline
&& (errbuf->b_sfname == NULL
- || path_is_absolute((char_u *)errbuf->b_sfname))) {
+ || path_is_absolute(errbuf->b_sfname))) {
if (*dirname == NUL) {
- os_dirname((char_u *)dirname, MAXPATHL);
+ os_dirname(dirname, MAXPATHL);
}
- shorten_buf_fname(errbuf, (char_u *)dirname, false);
+ shorten_buf_fname(errbuf, dirname, false);
}
- STRLCPY(IObuff, errbuf->b_fname, IOSIZE);
+ xstrlcpy(IObuff, errbuf->b_fname, IOSIZE);
}
- len = (int)STRLEN(IObuff);
+ len = (int)strlen(IObuff);
} else {
len = 0;
}
@@ -3945,15 +3982,15 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
IObuff[len++] = '|';
}
if (qfp->qf_lnum > 0) {
- qf_range_text(qfp, (char *)IObuff + len, IOSIZE - len);
- len += (int)STRLEN(IObuff + len);
+ qf_range_text(qfp, IObuff + len, IOSIZE - len);
+ len += (int)strlen(IObuff + len);
- snprintf((char *)IObuff + len, (size_t)(IOSIZE - len), "%s", qf_types(qfp->qf_type,
- qfp->qf_nr));
- 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);
} else if (qfp->qf_pattern != NULL) {
- qf_fmt_text(qfp->qf_pattern, (char *)IObuff + len, IOSIZE - len);
- len += (int)STRLEN(IObuff + len);
+ qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len);
+ len += (int)strlen(IObuff + len);
}
if (len < IOSIZE - 2) {
IObuff[len++] = '|';
@@ -3964,11 +4001,11 @@ static int qf_buf_add_line(qf_list_T *qfl, buf_T *buf, linenr_T lnum, const qfli
// 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,
- (char *)IObuff + len, IOSIZE - len);
+ IObuff + len, IOSIZE - len);
}
if (ml_append_buf(buf, lnum, IObuff,
- (colnr_T)STRLEN(IObuff) + 1, false) == FAIL) {
+ (colnr_T)strlen(IObuff) + 1, false) == FAIL) {
return FAIL;
}
return OK;
@@ -3980,6 +4017,12 @@ static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long
{
Callback *cb = &qftf_cb;
list_T *qftf_list = NULL;
+ static bool recursive = false;
+
+ if (recursive) {
+ return NULL; // this doesn't work properly recursively
+ }
+ recursive = true;
// If 'quickfixtextfunc' is set, then use the user-supplied function to get
// the text to display. Use the local value of 'quickfixtextfunc' if it is
@@ -4013,6 +4056,7 @@ static list_T *call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long
tv_dict_unref(dict);
}
+ recursive = false;
return qftf_list;
}
@@ -4039,7 +4083,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
}
// Check if there is anything to display
- if (qfl != NULL) {
+ if (qfl != NULL && qfl->qf_start != NULL) {
char dirname[MAXPATHL];
*dirname = NUL;
@@ -4108,7 +4152,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("ft", 0L, "qf", OPT_LOCAL);
+ set_option_value_give_err("ft", 0L, "qf", OPT_LOCAL);
curbuf->b_p_ma = false;
keep_filetype = true; // don't detect 'filetype'
@@ -4118,7 +4162,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q
curbuf->b_ro_locked--;
// make sure it will be redrawn
- redraw_curbuf_later(NOT_VALID);
+ redraw_curbuf_later(UPD_NOT_VALID);
}
// Restore KeyTyped, setting 'filetype' may reset it.
@@ -4151,14 +4195,16 @@ static int qf_id2nr(const qf_info_T *const qi, const unsigned qfid)
static int qf_restore_list(qf_info_T *qi, unsigned save_qfid)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (qf_get_curlist(qi)->qf_id != save_qfid) {
- const int curlist = qf_id2nr(qi, save_qfid);
- if (curlist < 0) {
- // list is not present
- return FAIL;
- }
- qi->qf_curlist = curlist;
+ if (qf_get_curlist(qi)->qf_id == save_qfid) {
+ return OK;
+ }
+
+ const int curlist = qf_id2nr(qi, save_qfid);
+ if (curlist < 0) {
+ // list is not present
+ return FAIL;
}
+ qi->qf_curlist = curlist;
return OK;
}
@@ -4175,15 +4221,14 @@ static void qf_jump_first(qf_info_T *qi, unsigned save_qfid, int forceit)
}
}
-// Return TRUE when using ":vimgrep" for ":grep".
+// Return true when using ":vimgrep" for ":grep".
int grep_internal(cmdidx_T cmdidx)
{
return (cmdidx == CMD_grep
|| cmdidx == CMD_lgrep
|| cmdidx == CMD_grepadd
|| cmdidx == CMD_lgrepadd)
- && STRCMP("internal",
- *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
+ && strcmp("internal", *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0;
}
// Return the make/grep autocmd name.
@@ -4213,16 +4258,16 @@ static char *make_get_auname(cmdidx_T cmdidx)
static char *make_get_fullcmd(const char *makecmd, const char *fname)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
{
- size_t len = STRLEN(p_shq) * 2 + STRLEN(makecmd) + 1;
+ size_t len = strlen(p_shq) * 2 + strlen(makecmd) + 1;
if (*p_sp != NUL) {
- len += STRLEN(p_sp) + STRLEN(fname) + 3;
+ len += strlen(p_sp) + strlen(fname) + 3;
}
char *const cmd = xmalloc(len);
- snprintf(cmd, len, "%s%s%s", (char *)p_shq, (char *)makecmd, (char *)p_shq);
+ snprintf(cmd, len, "%s%s%s", p_shq, (char *)makecmd, p_shq);
// If 'shellpipe' empty: don't redirect to 'errorfile'.
if (*p_sp != NUL) {
- append_redir(cmd, len, (char *)p_sp, (char *)fname);
+ append_redir(cmd, len, p_sp, (char *)fname);
}
// Display the fully formed command. Output a newline if there's something
@@ -4241,7 +4286,7 @@ static char *make_get_fullcmd(const char *makecmd, const char *fname)
// Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd"
void ex_make(exarg_T *eap)
{
- char *enc = (*curbuf->b_p_menc != NUL) ? (char *)curbuf->b_p_menc : (char *)p_menc;
+ char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
// Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal".
if (grep_internal(eap->cmdidx)) {
@@ -4275,10 +4320,17 @@ void ex_make(exarg_T *eap)
incr_quickfix_busy();
- int res = qf_init(wp, fname, (eap->cmdidx != CMD_make
- && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
- (eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd),
- qf_cmdtitle(*eap->cmdlinep), enc);
+ char *errorformat = p_efm;
+ bool newlist = true;
+
+ if (eap->cmdidx != CMD_make && eap->cmdidx != CMD_lmake) {
+ errorformat = p_gefm;
+ }
+ if (eap->cmdidx == CMD_grepadd || eap->cmdidx == CMD_lgrepadd) {
+ newlist = false;
+ }
+
+ int res = qf_init(wp, fname, errorformat, newlist, qf_cmdtitle(*eap->cmdlinep), enc);
qf_info_T *qi = &ql_info;
if (wp != NULL) {
@@ -4319,7 +4371,7 @@ static char *get_mef_name(void)
static int off = 0;
if (*p_mef == NUL) {
- name = (char *)vim_tempname();
+ name = vim_tempname();
if (name == NULL) {
emsg(_(e_notmp));
}
@@ -4328,7 +4380,7 @@ static char *get_mef_name(void)
char *p;
- for (p = p_mef; *p; ++p) {
+ for (p = p_mef; *p; p++) {
if (p[0] == '#' && p[1] == '#') {
break;
}
@@ -4345,9 +4397,9 @@ static char *get_mef_name(void)
} else {
off += 19;
}
- name = xmalloc(STRLEN(p_mef) + 30);
+ name = xmalloc(strlen(p_mef) + 30);
STRCPY(name, p_mef);
- snprintf(name + (p - p_mef), STRLEN(name), "%d%d", start, off);
+ snprintf(name + (p - p_mef), strlen(name), "%d%d", start, off);
STRCAT(name, p + 2);
// Don't accept a symbolic link, it's a security risk.
FileInfo file_info;
@@ -4832,7 +4884,7 @@ static void qf_get_nth_below_entry(qfline_T *entry_arg, linenr_T n, bool linewis
}
/// Get the nth quickfix entry above the specified entry. Searches backwards in
-/// the list. If linewise is TRUE, then treat multiple entries on a single line
+/// the list. If linewise is true, then treat multiple entries on a single line
/// as one.
static void qf_get_nth_above_entry(qfline_T *entry, linenr_T n, bool linewise, int *errornr)
FUNC_ATTR_NONNULL_ALL
@@ -4898,7 +4950,7 @@ void ex_cbelow(exarg_T *eap)
|| eap->cmdidx == CMD_cafter) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY;
if (!(curbuf->b_has_qf_entry & buf_has_flag)) {
- emsg(_(e_quickfix));
+ emsg(_(e_no_errors));
return;
}
@@ -4910,7 +4962,7 @@ void ex_cbelow(exarg_T *eap)
qf_list_T *qfl = qf_get_curlist(qi);
// check if the list has valid errors
if (!qf_list_has_valid_entries(qfl)) {
- emsg(_(e_quickfix));
+ emsg(_(e_no_errors));
return;
}
@@ -4981,7 +5033,7 @@ void ex_cfile(exarg_T *eap)
set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0);
}
- char *enc = (*curbuf->b_p_menc != NUL) ? (char *)curbuf->b_p_menc : (char *)p_menc;
+ char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
if (is_loclist_cmd(eap->cmdidx)) {
wp = curwin;
@@ -4997,8 +5049,8 @@ void ex_cfile(exarg_T *eap)
// first error.
// :caddfile adds to an existing quickfix list. If there is no
// quickfix list then a new list is created.
- int res = qf_init(wp, (char *)p_ef, p_efm, (eap->cmdidx != CMD_caddfile
- && eap->cmdidx != CMD_laddfile),
+ int res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
+ && eap->cmdidx != CMD_laddfile),
qf_cmdtitle(*eap->cmdlinep), enc);
if (wp != NULL) {
qi = GET_LOC_LIST(wp);
@@ -5062,7 +5114,7 @@ static void vgr_init_regmatch(regmmatch_T *regmatch, char *s)
emsg(_(e_noprevre));
return;
}
- regmatch->regprog = vim_regcomp((char *)last_search_pat(), RE_MAGIC);
+ regmatch->regprog = vim_regcomp(last_search_pat(), RE_MAGIC);
} else {
regmatch->regprog = vim_regcomp(s, RE_MAGIC);
}
@@ -5075,7 +5127,7 @@ static void vgr_init_regmatch(regmmatch_T *regmatch, char *s)
static void vgr_display_fname(char *fname)
{
msg_start();
- char *p = (char *)msg_strtrunc((char_u *)fname, true);
+ char *p = msg_strtrunc(fname, true);
if (p == NULL) {
msg_outtrans(fname);
} else {
@@ -5120,11 +5172,10 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid, char *titl
// An autocmd has freed the location list
emsg(_(e_current_location_list_was_changed));
return false;
- } else {
- // Quickfix list is not found, create a new one.
- qf_new_list(qi, title);
- return true;
}
+ // Quickfix list is not found, create a new one.
+ qf_new_list(qi, title);
+ return true;
}
if (qf_restore_list(qi, qfid) == FAIL) {
return false;
@@ -5140,6 +5191,7 @@ 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);
for (linenr_T lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; lnum++) {
colnr_T col = 0;
@@ -5154,7 +5206,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,
- (char *)ml_get_buf(buf, regmatch->startpos[0].lnum + lnum, false),
+ ml_get_buf(buf, regmatch->startpos[0].lnum + lnum, false),
regmatch->startpos[0].lnum + lnum,
regmatch->endpos[0].lnum + lnum,
regmatch->startpos[0].col + 1,
@@ -5176,20 +5228,18 @@ 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, false))) {
break;
}
}
} else {
- const size_t pat_len = STRLEN(spat);
- char *const str = (char *)ml_get_buf(buf, lnum, false);
+ char *const str = ml_get_buf(buf, lnum, false);
int score;
uint32_t matches[MAX_FUZZY_MATCHES];
const size_t sz = sizeof(matches) / sizeof(matches[0]);
// Fuzzy string match
- while (fuzzy_match((char_u *)str + col, (char_u *)spat, false, &score, matches,
- (int)sz) > 0) {
+ 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
// buffer will be wiped out below.
@@ -5220,7 +5270,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp
break;
}
col = (colnr_T)matches[pat_len - 1] + col + 1;
- if (col > (colnr_T)STRLEN(str)) {
+ if (col > (colnr_T)strlen(str)) {
break;
}
}
@@ -5236,7 +5286,7 @@ static bool vgr_match_buflines(qf_list_T *qfl, char *fname, buf_T *buf, char *sp
/// Jump to the first match and update the directory.
static void vgr_jump_to_match(qf_info_T *qi, int forceit, bool *redraw_for_dummy,
- buf_T *first_match_buf, char *target_dir)
+ buf_T *first_match_buf, char *target_dir) // NOLINT(readability-non-const-parameter)
{
buf_T *buf = curbuf;
qf_jump(qi, 0, 0, forceit);
@@ -5262,8 +5312,8 @@ static bool existing_swapfile(const buf_T *buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (buf->b_ml.ml_mfp != NULL && buf->b_ml.ml_mfp->mf_fname != NULL) {
- const char *const fname = (char *)buf->b_ml.ml_mfp->mf_fname;
- const size_t len = STRLEN(fname);
+ const char *const fname = buf->b_ml.ml_mfp->mf_fname;
+ const size_t len = strlen(fname);
return fname[len - 1] != 'p' || fname[len - 2] != 'w';
}
@@ -5305,10 +5355,8 @@ static int vgr_process_args(exarg_T *eap, vgr_args_T *args)
}
// Parse the list of arguments, wildcards have already been expanded.
- if (get_arglist_exp((char_u *)p, &args->fcount, &args->fnames, true) == FAIL) {
- return FAIL;
- }
- if (args->fcount == 0) {
+ if (get_arglist_exp(p, &args->fcount, &args->fnames, true) == FAIL
+ || args->fcount == 0) {
emsg(_(e_nomatch));
return FAIL;
}
@@ -5330,11 +5378,11 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo
// Remember the current directory, because a BufRead autocommand that does
// ":lcd %:p:h" changes the meaning of short path names.
- os_dirname((char_u *)dirname_start, MAXPATHL);
+ os_dirname(dirname_start, MAXPATHL);
time_t seconds = (time_t)0;
for (int fi = 0; fi < cmd_args->fcount && !got_int && cmd_args->tomatch > 0; fi++) {
- char *fname = (char *)path_try_shorten_fname((char_u *)cmd_args->fnames[fi]);
+ char *fname = path_try_shorten_fname(cmd_args->fnames[fi]);
if (time(NULL) > seconds) {
// Display the file name every second or so, show the user we are
// working on it.
@@ -5419,7 +5467,7 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo
// directory we jumped to below.
if (buf == *first_match_buf
&& *target_dir == NULL
- && STRCMP(dirname_start, dirname_now) != 0) {
+ && strcmp(dirname_start, dirname_now) != 0) {
*target_dir = xstrdup(dirname_now);
}
@@ -5429,7 +5477,7 @@ static int vgr_process_files(win_T *wp, qf_info_T *qi, vgr_args_T *cmd_args, boo
// options!
aco_save_T aco;
aucmd_prepbuf(&aco, buf);
- apply_autocmds(EVENT_FILETYPE, (char *)buf->b_p_ft, buf->b_fname, true, buf);
+ apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, buf->b_fname, true, buf);
do_modelines(OPT_NOWIN);
aucmd_restbuf(&aco);
}
@@ -5541,8 +5589,8 @@ static void restore_start_dir(char *dirname_start)
{
char *dirname_now = xmalloc(MAXPATHL);
- os_dirname((char_u *)dirname_now, MAXPATHL);
- if (STRCMP(dirname_start, dirname_now) != 0) {
+ os_dirname(dirname_now, MAXPATHL);
+ if (strcmp(dirname_start, dirname_now) != 0) {
// If the directory has changed, change it back by building up an
// appropriate ex command and executing it.
exarg_T ea = {
@@ -5609,7 +5657,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin
if (readfile_result == OK
&& !got_int
&& !(curbuf->b_flags & BF_NEW)) {
- failed = FALSE;
+ failed = false;
if (curbuf != newbuf) {
// Bloody autocommands changed the buffer! Can happen when
// using netrw and editing a remote file. Use the current
@@ -5622,6 +5670,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin
// Restore curwin/curbuf and a few other things.
aucmd_restbuf(&aco);
+
if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) {
wipe_buffer(newbuf_to_wipe.br_buf, false);
}
@@ -5634,7 +5683,7 @@ static buf_T *load_dummy_buffer(char *fname, char *dirname_start, char *resultin
// When autocommands/'autochdir' option changed directory: go back.
// Let the caller know what the resulting dir was first, in case it is
// important.
- os_dirname((char_u *)resulting_dir, MAXPATHL);
+ os_dirname(resulting_dir, MAXPATHL);
restore_start_dir(dirname_start);
if (!bufref_valid(&newbufref)) {
@@ -5677,7 +5726,7 @@ static void wipe_dummy_buffer(buf_T *buf, char *dirname_start)
cleanup_T cs;
// Reset the error/interrupt/exception state here so that aborting()
- // returns FALSE when wiping out the buffer. Otherwise it doesn't
+ // returns false when wiping out the buffer. Otherwise it doesn't
// work when got_int is set.
enter_cleanup(&cs);
@@ -5696,12 +5745,14 @@ static void wipe_dummy_buffer(buf_T *buf, char *dirname_start)
// 'autochdir' option have changed it.
static void unload_dummy_buffer(buf_T *buf, char *dirname_start)
{
- if (curbuf != buf) { // safety check
- close_buffer(NULL, buf, DOBUF_UNLOAD, false, true);
-
- // When autocommands/'autochdir' option changed directory: go back.
- restore_start_dir(dirname_start);
+ if (curbuf == buf) { // safety check
+ return;
}
+
+ close_buffer(NULL, buf, DOBUF_UNLOAD, false, true);
+
+ // When autocommands/'autochdir' option changed directory: go back.
+ restore_start_dir(dirname_start);
}
/// Copy the specified quickfix entry items into a new dict and append the dict
@@ -5826,32 +5877,34 @@ static int qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict)
int status = FAIL;
// Only a List value is supported
- if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) {
- char *errorformat = p_efm;
- dictitem_T *efm_di;
- // If errorformat is supplied then use it, otherwise use the 'efm'
- // option setting
- if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
- if (efm_di->di_tv.v_type != VAR_STRING
- || efm_di->di_tv.vval.v_string == NULL) {
- return FAIL;
- }
- errorformat = efm_di->di_tv.vval.v_string;
- }
-
- list_T *l = tv_list_alloc(kListLenMayKnow);
- qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL);
+ if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) {
+ return FAIL;
+ }
- if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
- true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
- (void)get_errorlist(qi, NULL, 0, 0, l);
- qf_free(&qi->qf_lists[0]);
+ char *errorformat = p_efm;
+ dictitem_T *efm_di;
+ // If errorformat is supplied then use it, otherwise use the 'efm'
+ // option setting
+ if ((efm_di = tv_dict_find(what, S_LEN("efm"))) != NULL) {
+ if (efm_di->di_tv.v_type != VAR_STRING
+ || efm_di->di_tv.vval.v_string == NULL) {
+ return FAIL;
}
- xfree(qi);
+ errorformat = efm_di->di_tv.vval.v_string;
+ }
+
+ list_T *l = tv_list_alloc(kListLenMayKnow);
+ qf_info_T *const qi = qf_alloc_stack(QFLT_INTERNAL);
- tv_dict_add_list(retdict, S_LEN("items"), l);
- status = OK;
+ if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat,
+ true, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) {
+ (void)get_errorlist(qi, NULL, 0, 0, l);
+ qf_free(&qi->qf_lists[0]);
}
+ xfree(qi);
+
+ tv_dict_add_list(retdict, S_LEN("items"), l);
+ status = OK;
return status;
}
@@ -6500,7 +6553,7 @@ static int qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, const dictitem_T *di
// If the specified index is '$', then use the last entry
if (di->di_tv.v_type == VAR_STRING
&& di->di_tv.vval.v_string != NULL
- && STRCMP(di->di_tv.vval.v_string, "$") == 0) {
+ && strcmp(di->di_tv.vval.v_string, "$") == 0) {
newidx = qfl->qf_count;
} else {
// Otherwise use the specified index
@@ -6668,7 +6721,8 @@ int set_errorlist(win_T *wp, list_T *list, int action, char *title, dict_T *what
return retval;
}
-/// Mark the context as in use for all the lists in a quickfix stack.
+/// 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)
{
bool abort = false;
@@ -6679,6 +6733,9 @@ static bool mark_quickfix_ctx(qf_info_T *qi, int copyID)
&& ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) {
abort = set_ref_in_item(ctx, copyID, NULL, NULL);
}
+
+ Callback *cb = &qi->qf_lists[i].qf_qftf_cb;
+ abort = abort || set_ref_in_callback(cb, copyID, NULL, NULL);
}
return abort;
@@ -6693,6 +6750,11 @@ bool set_ref_in_quickfix(int copyID)
return abort;
}
+ abort = set_ref_in_callback(&qftf_cb, copyID, NULL, NULL);
+ if (abort) {
+ return abort;
+ }
+
FOR_ALL_TAB_WINDOWS(tp, win) {
if (win->w_llist != NULL) {
abort = mark_quickfix_ctx(win->w_llist, copyID);
@@ -6806,8 +6868,8 @@ void ex_cbuffer(exarg_T *eap)
char *qf_title = qf_cmdtitle(*eap->cmdlinep);
if (buf->b_sfname) {
- vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", qf_title, buf->b_sfname);
- qf_title = (char *)IObuff;
+ vim_snprintf(IObuff, IOSIZE, "%s (%s)", qf_title, buf->b_sfname);
+ qf_title = IObuff;
}
incr_quickfix_busy();
@@ -6885,43 +6947,45 @@ 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 ((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,
- (eap->cmdidx != CMD_caddexpr
- && eap->cmdidx != CMD_laddexpr),
- (linenr_T)0, (linenr_T)0,
- qf_cmdtitle(*eap->cmdlinep), NULL);
- if (qf_stack_empty(qi)) {
- decr_quickfix_busy();
- goto cleanup;
- }
- if (res >= 0) {
- qf_list_changed(qf_get_curlist(qi));
- }
- // Remember the current quickfix list identifier, so that we can
- // check for autocommands changing the current quickfix list.
- unsigned save_qfid = qf_get_curlist(qi)->qf_id;
- if (au_name != NULL) {
- apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
- }
- // Jump to the first error for a new list and if autocmds didn't
- // free the list.
- if (res > 0
- && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
- && qflist_valid(wp, save_qfid)) {
- // display the first error
- qf_jump_first(qi, save_qfid, eap->forceit);
- }
+ if (eval0(eap->arg, &tv, &eap->nextcmd, true) == FAIL) {
+ return;
+ }
+
+ 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,
+ (eap->cmdidx != CMD_caddexpr
+ && eap->cmdidx != CMD_laddexpr),
+ (linenr_T)0, (linenr_T)0,
+ qf_cmdtitle(*eap->cmdlinep), NULL);
+ if (qf_stack_empty(qi)) {
decr_quickfix_busy();
- } else {
- emsg(_("E777: String or List expected"));
+ goto cleanup;
}
-cleanup:
- tv_clear(&tv);
+ if (res >= 0) {
+ qf_list_changed(qf_get_curlist(qi));
+ }
+ // Remember the current quickfix list identifier, so that we can
+ // check for autocommands changing the current quickfix list.
+ unsigned save_qfid = qf_get_curlist(qi)->qf_id;
+ if (au_name != NULL) {
+ apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, curbuf->b_fname, true, curbuf);
+ }
+ // Jump to the first error for a new list and if autocmds didn't
+ // free the list.
+ if (res > 0
+ && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)
+ && qflist_valid(wp, save_qfid)) {
+ // display the first error
+ qf_jump_first(qi, save_qfid, eap->forceit);
+ }
+ decr_quickfix_busy();
+ } else {
+ emsg(_("E777: String or List expected"));
}
+cleanup:
+ tv_clear(&tv);
}
// Get the location list for ":lhelpgrep"
@@ -6952,10 +7016,10 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch)
linenr_T lnum = 1;
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) {
- char *line = (char *)IObuff;
+ char *line = IObuff;
if (vim_regexec(p_regmatch, line, (colnr_T)0)) {
- int l = (int)STRLEN(line);
+ int l = (int)strlen(line);
// remove trailing CR, LF, spaces, etc.
while (l > 0 && line[l - 1] <= ' ') {
@@ -6970,8 +7034,8 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch)
line,
lnum,
0,
- (int)(p_regmatch->startp[0] - (char_u *)line) + 1, // col
- (int)(p_regmatch->endp[0] - (char_u *)line)
+ (int)(p_regmatch->startp[0] - line) + 1, // col
+ (int)(p_regmatch->endp[0] - line)
+ 1, // end_col
false, // vis_col
NULL, // search pattern
@@ -6980,13 +7044,13 @@ static void hgr_search_file(qf_list_T *qfl, char *fname, regmatch_T *p_regmatch)
true) // valid
== QF_FAIL) {
got_int = true;
- if ((char_u *)line != IObuff) {
+ if (line != IObuff) {
xfree(line);
}
break;
}
}
- if ((char_u *)line != IObuff) {
+ if (line != IObuff) {
xfree(line);
}
lnum++;
@@ -7012,9 +7076,9 @@ static void hgr_search_files_in_dir(qf_list_T *qfl, char *dirname, regmatch_T *p
for (int fi = 0; fi < fcount && !got_int; fi++) {
// Skip files for a different language.
if (lang != NULL
- && STRNICMP(lang, fnames[fi] + STRLEN(fnames[fi]) - 3, 2) != 0
+ && STRNICMP(lang, fnames[fi] + strlen(fnames[fi]) - 3, 2) != 0
&& !(STRNICMP(lang, "en", 2) == 0
- && STRNICMP("txt", fnames[fi] + STRLEN(fnames[fi]) - 3, 3)
+ && STRNICMP("txt", fnames[fi] + strlen(fnames[fi]) - 3, 3)
== 0)) {
continue;
}
@@ -7033,11 +7097,11 @@ static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char
FUNC_ATTR_NONNULL_ARG(1, 2)
{
// Go through all directories in 'runtimepath'
- char *p = (char *)p_rtp;
+ char *p = p_rtp;
while (*p != NUL && !got_int) {
- copy_option_part(&p, (char *)NameBuff, MAXPATHL, ",");
+ copy_option_part(&p, NameBuff, MAXPATHL, ",");
- hgr_search_files_in_dir(qfl, (char *)NameBuff, p_regmatch, (char *)lang);
+ hgr_search_files_in_dir(qfl, NameBuff, p_regmatch, (char *)lang);
}
}
@@ -7045,7 +7109,7 @@ static void hgr_search_in_rtp(qf_list_T *qfl, regmatch_T *p_regmatch, const char
void ex_helpgrep(exarg_T *eap)
{
qf_info_T *qi = &ql_info;
- char *au_name = NULL;
+ char *au_name = NULL;
switch (eap->cmdidx) {
case CMD_helpgrep:
@@ -7062,9 +7126,11 @@ void ex_helpgrep(exarg_T *eap)
}
}
+ bool updated = false;
// Make 'cpoptions' empty, the 'l' flag should not be used here.
char *const save_cpo = p_cpo;
- p_cpo = (char *)empty_option;
+ const bool save_cpo_allocated = is_option_allocated("cpo");
+ p_cpo = empty_option;
bool new_qi = false;
if (is_loclist_cmd(eap->cmdidx)) {
@@ -7092,14 +7158,26 @@ void ex_helpgrep(exarg_T *eap)
qfl->qf_ptr = qfl->qf_start;
qfl->qf_index = 1;
qf_list_changed(qfl);
- qf_update_buffer(qi, NULL);
+ updated = true;
}
- if ((char_u *)p_cpo == empty_option) {
+ if (p_cpo == empty_option) {
p_cpo = save_cpo;
} else {
- // Darn, some plugin changed the value.
- free_string_option((char_u *)save_cpo);
+ // 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);
+ }
+ if (save_cpo_allocated) {
+ free_string_option(save_cpo);
+ }
+ }
+
+ if (updated) {
+ // This may open a window and source scripts, do this after 'cpo' was
+ // restored.
+ qf_update_buffer(qi, NULL);
}
if (au_name != NULL) {
@@ -7128,7 +7206,9 @@ void ex_helpgrep(exarg_T *eap)
if (new_qi) {
ll_free_all(&qi);
}
- } else if (curwin->w_llist == NULL) {
+ } else if (curwin->w_llist == NULL && new_qi) {
+ // current window didn't have a location list associated with it
+ // before. Associate the new location list now.
curwin->w_llist = qi;
}
}
@@ -7158,14 +7238,14 @@ static void get_qf_loc_list(int is_qf, win_T *wp, typval_T *what_arg, typval_T *
}
/// "getloclist()" function
-void f_getloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getloclist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
win_T *wp = find_win_by_nr_or_id(&argvars[0]);
get_qf_loc_list(false, wp, &argvars[1], rettv);
}
/// "getqflist()" functions
-void f_getqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_getqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
get_qf_loc_list(true, NULL, &argvars[0], rettv);
}
@@ -7252,7 +7332,7 @@ skip_args:
}
/// "setloclist()" function
-void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_setloclist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
rettv->vval.v_number = -1;
@@ -7263,7 +7343,7 @@ void f_setloclist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
/// "setqflist()" function
-void f_setqflist(typval_T *argvars, typval_T *rettv, FunPtr fptr)
+void f_setqflist(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
set_qf_ll_list(NULL, argvars, rettv);
}