mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
updated for version 7.0025
This commit is contained in:
242
src/quickfix.c
242
src/quickfix.c
@@ -86,6 +86,7 @@ struct eformat
|
||||
/* '-' do not include this line */
|
||||
};
|
||||
|
||||
static int qf_init_ext __ARGS((char_u *efile, buf_T *buf, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
|
||||
static void qf_new_list __ARGS((void));
|
||||
static int qf_add_entry __ARGS((struct qf_line **prevp, char_u *dir, char_u *fname, char_u *mesg, long lnum, int col, int virt_col, int nr, int type, int valid));
|
||||
static void qf_msg __ARGS((void));
|
||||
@@ -106,7 +107,8 @@ static void qf_fill_buffer __ARGS((void));
|
||||
static char_u *get_mef_name __ARGS((void));
|
||||
|
||||
/*
|
||||
* Read the errorfile into memory, line by line, building the error list.
|
||||
* Read the errorfile "efile" into memory, line by line, building the error
|
||||
* list.
|
||||
* Return -1 for error, number of errors for success.
|
||||
*/
|
||||
int
|
||||
@@ -114,6 +116,29 @@ qf_init(efile, errorformat, newlist)
|
||||
char_u *efile;
|
||||
char_u *errorformat;
|
||||
int newlist; /* TRUE: start a new error list */
|
||||
{
|
||||
if (efile == NULL)
|
||||
return FAIL;
|
||||
return qf_init_ext(efile, curbuf, errorformat, newlist,
|
||||
(linenr_T)0, (linenr_T)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the errorfile "efile" into memory, line by line, building the error
|
||||
* list.
|
||||
* Alternative: when "efile" is null read errors from buffer "buf".
|
||||
* Always use 'errorformat' from "buf" if there is a local value.
|
||||
* Then lnumfirst and lnumlast specify the range of lines to use.
|
||||
* Return -1 for error, number of errors for success.
|
||||
*/
|
||||
static int
|
||||
qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
|
||||
char_u *efile;
|
||||
buf_T *buf;
|
||||
char_u *errorformat;
|
||||
int newlist; /* TRUE: start a new error list */
|
||||
linenr_T lnumfirst; /* first line number to use */
|
||||
linenr_T lnumlast; /* last line number to use */
|
||||
{
|
||||
char_u *namebuf;
|
||||
char_u *errmsg;
|
||||
@@ -122,9 +147,10 @@ qf_init(efile, errorformat, newlist)
|
||||
char_u use_virt_col = FALSE;
|
||||
int type = 0;
|
||||
int valid;
|
||||
linenr_T buflnum = lnumfirst;
|
||||
long lnum = 0L;
|
||||
int enr = 0;
|
||||
FILE *fd;
|
||||
FILE *fd = NULL;
|
||||
struct qf_line *qfprev = NULL; /* init to make SASC shut up */
|
||||
char_u *efmp;
|
||||
struct eformat *fmt_first = NULL;
|
||||
@@ -163,15 +189,12 @@ qf_init(efile, errorformat, newlist)
|
||||
{'v', "\\d\\+"}
|
||||
};
|
||||
|
||||
if (efile == NULL)
|
||||
return FAIL;
|
||||
|
||||
namebuf = alloc(CMDBUFFSIZE + 1);
|
||||
errmsg = alloc(CMDBUFFSIZE + 1);
|
||||
if (namebuf == NULL || errmsg == NULL)
|
||||
goto qf_init_end;
|
||||
|
||||
if ((fd = mch_fopen((char *)efile, "r")) == NULL)
|
||||
if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL)
|
||||
{
|
||||
EMSG2(_(e_openerrf), efile);
|
||||
goto qf_init_end;
|
||||
@@ -191,8 +214,8 @@ qf_init(efile, errorformat, newlist)
|
||||
* regex prog. Only a few % characters are allowed.
|
||||
*/
|
||||
/* Use the local value of 'errorformat' if it's set. */
|
||||
if (errorformat == p_efm && *curbuf->b_p_efm != NUL)
|
||||
efm = curbuf->b_p_efm;
|
||||
if (errorformat == p_efm && *buf->b_p_efm != NUL)
|
||||
efm = buf->b_p_efm;
|
||||
else
|
||||
efm = errorformat;
|
||||
/*
|
||||
@@ -405,8 +428,18 @@ qf_init(efile, errorformat, newlist)
|
||||
* Read the lines in the error file one by one.
|
||||
* Try to recognize one of the error formats in each line.
|
||||
*/
|
||||
while (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) != NULL && !got_int)
|
||||
while (!got_int)
|
||||
{
|
||||
/* Get the next line. */
|
||||
if (fd == NULL)
|
||||
{
|
||||
if (buflnum > lnumlast)
|
||||
break;
|
||||
STRNCPY(IObuff, ml_get_buf(buf, buflnum++, FALSE), CMDBUFFSIZE - 2);
|
||||
}
|
||||
else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
|
||||
break;
|
||||
|
||||
IObuff[CMDBUFFSIZE - 2] = NUL; /* for very long lines */
|
||||
if ((efmp = vim_strrchr(IObuff, '\n')) != NULL)
|
||||
*efmp = NUL;
|
||||
@@ -594,7 +627,7 @@ restofline:
|
||||
goto error2;
|
||||
line_breakcheck();
|
||||
}
|
||||
if (!ferror(fd))
|
||||
if (fd == NULL || !ferror(fd))
|
||||
{
|
||||
if (qf_lists[qf_curlist].qf_index == 0) /* no valid entry found */
|
||||
{
|
||||
@@ -618,7 +651,8 @@ error2:
|
||||
if (qf_curlist > 0)
|
||||
--qf_curlist;
|
||||
qf_init_ok:
|
||||
fclose(fd);
|
||||
if (fd != NULL)
|
||||
fclose(fd);
|
||||
for (fmt_ptr = fmt_first; fmt_ptr != NULL; fmt_ptr = fmt_first)
|
||||
{
|
||||
fmt_first = fmt_ptr->next;
|
||||
@@ -2025,6 +2059,18 @@ buf_hide(buf)
|
||||
return (p_hid || cmdmod.hide);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE when using ":vimgrep" for ":grep".
|
||||
*/
|
||||
int
|
||||
grep_internal(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
return ((eap->cmdidx == CMD_grep || eap->cmdidx == CMD_grepadd)
|
||||
&& STRCMP("internal",
|
||||
*curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used for ":make", ":grep" and ":grepadd".
|
||||
*/
|
||||
@@ -2036,6 +2082,13 @@ ex_make(eap)
|
||||
char_u *cmd;
|
||||
unsigned len;
|
||||
|
||||
/* Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". */
|
||||
if (grep_internal(eap))
|
||||
{
|
||||
ex_vimgrep(eap);
|
||||
return;
|
||||
}
|
||||
|
||||
autowrite_all();
|
||||
name = get_mef_name();
|
||||
if (name == NULL)
|
||||
@@ -2075,7 +2128,7 @@ ex_make(eap)
|
||||
#endif
|
||||
|
||||
if (qf_init(name, eap->cmdidx != CMD_make ? p_gefm : p_efm,
|
||||
eap->cmdidx != CMD_grepadd) > 0
|
||||
eap->cmdidx != CMD_grepadd) > 0
|
||||
&& !eap->forceit)
|
||||
qf_jump(0, 0, FALSE); /* display first error */
|
||||
|
||||
@@ -2189,6 +2242,171 @@ ex_cfile(eap)
|
||||
qf_jump(0, 0, eap->forceit); /* display first error */
|
||||
}
|
||||
|
||||
/*
|
||||
* ":vimgrep {pattern} file(s)"
|
||||
*/
|
||||
void
|
||||
ex_vimgrep(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
regmatch_T regmatch;
|
||||
char_u *save_cpo;
|
||||
int fcount;
|
||||
char_u **fnames;
|
||||
char_u *p;
|
||||
int i;
|
||||
FILE *fd;
|
||||
int fi;
|
||||
struct qf_line *prevp = NULL;
|
||||
long lnum;
|
||||
garray_T ga;
|
||||
|
||||
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
|
||||
save_cpo = p_cpo;
|
||||
p_cpo = empty_option;
|
||||
|
||||
/* Get the search pattern */
|
||||
regmatch.regprog = NULL;
|
||||
p = skip_regexp(eap->arg + 1, *eap->arg, TRUE, NULL);
|
||||
if (*p != *eap->arg)
|
||||
{
|
||||
EMSG(_("E682: Invalid search pattern or delimiter"));
|
||||
goto theend;
|
||||
}
|
||||
*p++ = NUL;
|
||||
regmatch.regprog = vim_regcomp(eap->arg + 1, RE_MAGIC);
|
||||
if (regmatch.regprog == NULL)
|
||||
goto theend;
|
||||
regmatch.rm_ic = FALSE;
|
||||
|
||||
p = skipwhite(p);
|
||||
if (*p == NUL)
|
||||
{
|
||||
EMSG(_("E683: File name missing or invalid pattern"));
|
||||
goto theend;
|
||||
}
|
||||
|
||||
if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_vimgrepadd)
|
||||
|| qf_curlist == qf_listcount)
|
||||
/* make place for a new list */
|
||||
qf_new_list();
|
||||
else if (qf_lists[qf_curlist].qf_count > 0)
|
||||
/* Adding to existing list, find last entry. */
|
||||
for (prevp = qf_lists[qf_curlist].qf_start;
|
||||
prevp->qf_next != prevp; prevp = prevp->qf_next)
|
||||
;
|
||||
|
||||
/* parse the list of arguments */
|
||||
if (get_arglist(&ga, p) == FAIL)
|
||||
goto theend;
|
||||
i = gen_expand_wildcards(ga.ga_len, (char_u **)ga.ga_data,
|
||||
&fcount, &fnames, EW_FILE|EW_NOTFOUND);
|
||||
ga_clear(&ga);
|
||||
if (i == FAIL)
|
||||
goto theend;
|
||||
if (fcount == 0)
|
||||
{
|
||||
EMSG(_(e_nomatch));
|
||||
goto theend;
|
||||
}
|
||||
|
||||
for (fi = 0; fi < fcount && !got_int; ++fi)
|
||||
{
|
||||
fd = fopen((char *)fnames[fi], "r");
|
||||
if (fd == NULL)
|
||||
smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]);
|
||||
else
|
||||
{
|
||||
lnum = 1;
|
||||
while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int)
|
||||
{
|
||||
if (vim_regexec(®match, IObuff, (colnr_T)0))
|
||||
{
|
||||
int l = STRLEN(IObuff);
|
||||
|
||||
/* remove trailing CR, LF, spaces, etc. */
|
||||
while (l > 0 && IObuff[l - 1] <= ' ')
|
||||
IObuff[--l] = NUL;
|
||||
|
||||
if (qf_add_entry(&prevp,
|
||||
NULL, /* dir */
|
||||
fnames[fi],
|
||||
IObuff,
|
||||
lnum,
|
||||
(int)(regmatch.startp[0] - IObuff) + 1,/* col */
|
||||
FALSE, /* virt_col */
|
||||
0, /* nr */
|
||||
0, /* type */
|
||||
TRUE /* valid */
|
||||
) == FAIL)
|
||||
{
|
||||
got_int = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++lnum;
|
||||
line_breakcheck();
|
||||
}
|
||||
fclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
FreeWild(fcount, fnames);
|
||||
|
||||
qf_lists[qf_curlist].qf_nonevalid = FALSE;
|
||||
qf_lists[qf_curlist].qf_ptr = qf_lists[qf_curlist].qf_start;
|
||||
qf_lists[qf_curlist].qf_index = 1;
|
||||
|
||||
#ifdef FEAT_WINDOWS
|
||||
qf_update_buffer();
|
||||
#endif
|
||||
|
||||
/* Jump to first match. */
|
||||
if (qf_lists[qf_curlist].qf_count > 0)
|
||||
qf_jump(0, 0, FALSE);
|
||||
|
||||
theend:
|
||||
vim_free(regmatch.regprog);
|
||||
|
||||
/* Only resture 'cpo' when it wasn't set in the mean time. */
|
||||
if (p_cpo == empty_option)
|
||||
p_cpo = save_cpo;
|
||||
else
|
||||
free_string_option(save_cpo);
|
||||
}
|
||||
|
||||
/*
|
||||
* ":[range]cbuffer [bufnr]" command.
|
||||
*/
|
||||
void
|
||||
ex_cbuffer(eap)
|
||||
exarg_T *eap;
|
||||
{
|
||||
buf_T *buf = NULL;
|
||||
|
||||
if (*eap->arg == NUL)
|
||||
buf = curbuf;
|
||||
else if (*skipwhite(skipdigits(eap->arg)) == NUL)
|
||||
buf = buflist_findnr(atoi((char *)eap->arg));
|
||||
if (buf == NULL)
|
||||
EMSG(_(e_invarg));
|
||||
else if (buf->b_ml.ml_mfp == NULL)
|
||||
EMSG(_("E681: Buffer is not loaded"));
|
||||
else
|
||||
{
|
||||
if (eap->addr_count == 0)
|
||||
{
|
||||
eap->line1 = 1;
|
||||
eap->line2 = buf->b_ml.ml_line_count;
|
||||
}
|
||||
if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count
|
||||
|| eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
|
||||
EMSG(_(e_invrange));
|
||||
else
|
||||
qf_init_ext(NULL, buf, p_efm, TRUE, eap->line1, eap->line2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ":helpgrep {pattern}"
|
||||
*/
|
||||
|
Reference in New Issue
Block a user