mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
patch 8.1.0010: efm_to_regpat() is too long
Problem: efm_to_regpat() is too long. Solution: Split off three functions. (Yegappan Lakshmanan, closes #2924)
This commit is contained in:
265
src/quickfix.c
265
src/quickfix.c
@@ -227,20 +227,173 @@ static struct fmtpattern
|
|||||||
{'o', ".\\+"}
|
{'o', ".\\+"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert an errorformat pattern to a regular expression pattern.
|
||||||
|
* See fmt_pat definition above for the list of supported patterns.
|
||||||
|
*/
|
||||||
|
static char_u *
|
||||||
|
fmtpat_to_regpat(
|
||||||
|
char_u *efmp,
|
||||||
|
efm_T *fmt_ptr,
|
||||||
|
int idx,
|
||||||
|
int round,
|
||||||
|
char_u *ptr,
|
||||||
|
char_u *errmsg)
|
||||||
|
{
|
||||||
|
char_u *srcptr;
|
||||||
|
|
||||||
|
if (fmt_ptr->addr[idx])
|
||||||
|
{
|
||||||
|
/* Each errorformat pattern can occur only once */
|
||||||
|
sprintf((char *)errmsg,
|
||||||
|
_("E372: Too many %%%c in format string"), *efmp);
|
||||||
|
EMSG(errmsg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((idx && idx < 6
|
||||||
|
&& vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
|
||||||
|
|| (idx == 6
|
||||||
|
&& vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL))
|
||||||
|
{
|
||||||
|
sprintf((char *)errmsg,
|
||||||
|
_("E373: Unexpected %%%c in format string"), *efmp);
|
||||||
|
EMSG(errmsg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fmt_ptr->addr[idx] = (char_u)++round;
|
||||||
|
*ptr++ = '\\';
|
||||||
|
*ptr++ = '(';
|
||||||
|
#ifdef BACKSLASH_IN_FILENAME
|
||||||
|
if (*efmp == 'f')
|
||||||
|
{
|
||||||
|
/* Also match "c:" in the file name, even when
|
||||||
|
* checking for a colon next: "%f:".
|
||||||
|
* "\%(\a:\)\=" */
|
||||||
|
STRCPY(ptr, "\\%(\\a:\\)\\=");
|
||||||
|
ptr += 10;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (*efmp == 'f' && efmp[1] != NUL)
|
||||||
|
{
|
||||||
|
if (efmp[1] != '\\' && efmp[1] != '%')
|
||||||
|
{
|
||||||
|
/* A file name may contain spaces, but this isn't
|
||||||
|
* in "\f". For "%f:%l:%m" there may be a ":" in
|
||||||
|
* the file name. Use ".\{-1,}x" instead (x is
|
||||||
|
* the next character), the requirement that :999:
|
||||||
|
* follows should work. */
|
||||||
|
STRCPY(ptr, ".\\{-1,}");
|
||||||
|
ptr += 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* File name followed by '\\' or '%': include as
|
||||||
|
* many file name chars as possible. */
|
||||||
|
STRCPY(ptr, "\\f\\+");
|
||||||
|
ptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcptr = (char_u *)fmt_pat[idx].pattern;
|
||||||
|
while ((*ptr = *srcptr++) != NUL)
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
*ptr++ = '\\';
|
||||||
|
*ptr++ = ')';
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert a scanf like format in 'errorformat' to a regular expression.
|
||||||
|
*/
|
||||||
|
static char_u *
|
||||||
|
scanf_fmt_to_regpat(
|
||||||
|
char_u *efm,
|
||||||
|
int len,
|
||||||
|
char_u **pefmp,
|
||||||
|
char_u *ptr,
|
||||||
|
char_u *errmsg)
|
||||||
|
{
|
||||||
|
char_u *efmp = *pefmp;
|
||||||
|
|
||||||
|
if (*++efmp == '[' || *efmp == '\\')
|
||||||
|
{
|
||||||
|
if ((*ptr++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
|
||||||
|
{
|
||||||
|
if (efmp[1] == '^')
|
||||||
|
*ptr++ = *++efmp;
|
||||||
|
if (efmp < efm + len)
|
||||||
|
{
|
||||||
|
*ptr++ = *++efmp; /* could be ']' */
|
||||||
|
while (efmp < efm + len
|
||||||
|
&& (*ptr++ = *++efmp) != ']')
|
||||||
|
/* skip */;
|
||||||
|
if (efmp == efm + len)
|
||||||
|
{
|
||||||
|
EMSG(_("E374: Missing ] in format string"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (efmp < efm + len) /* %*\D, %*\s etc. */
|
||||||
|
*ptr++ = *++efmp;
|
||||||
|
*ptr++ = '\\';
|
||||||
|
*ptr++ = '+';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
|
||||||
|
sprintf((char *)errmsg,
|
||||||
|
_("E375: Unsupported %%%c in format string"), *efmp);
|
||||||
|
EMSG(errmsg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pefmp = efmp;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analyze/parse an errorformat prefix.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
efm_analyze_prefix(char_u **pefmp, efm_T *fmt_ptr, char_u *errmsg)
|
||||||
|
{
|
||||||
|
char_u *efmp = *pefmp;
|
||||||
|
|
||||||
|
if (vim_strchr((char_u *)"+-", *efmp) != NULL)
|
||||||
|
fmt_ptr->flags = *efmp++;
|
||||||
|
if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
|
||||||
|
fmt_ptr->prefix = *efmp;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf((char *)errmsg,
|
||||||
|
_("E376: Invalid %%%c in format string prefix"), *efmp);
|
||||||
|
EMSG(errmsg);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pefmp = efmp;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Converts a 'errorformat' string to regular expression pattern
|
* Converts a 'errorformat' string to regular expression pattern
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
efm_to_regpat(
|
efm_to_regpat(
|
||||||
char_u *efm,
|
char_u *efm,
|
||||||
int len,
|
int len,
|
||||||
efm_T *fmt_ptr,
|
efm_T *fmt_ptr,
|
||||||
char_u *regpat,
|
char_u *regpat,
|
||||||
char_u *errmsg)
|
char_u *errmsg)
|
||||||
{
|
{
|
||||||
char_u *ptr;
|
char_u *ptr;
|
||||||
char_u *efmp;
|
char_u *efmp;
|
||||||
char_u *srcptr;
|
|
||||||
int round;
|
int round;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
@@ -260,102 +413,17 @@ efm_to_regpat(
|
|||||||
break;
|
break;
|
||||||
if (idx < FMT_PATTERNS)
|
if (idx < FMT_PATTERNS)
|
||||||
{
|
{
|
||||||
if (fmt_ptr->addr[idx])
|
ptr = fmtpat_to_regpat(efmp, fmt_ptr, idx, round, ptr,
|
||||||
{
|
errmsg);
|
||||||
sprintf((char *)errmsg,
|
if (ptr == NULL)
|
||||||
_("E372: Too many %%%c in format string"), *efmp);
|
|
||||||
EMSG(errmsg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
round++;
|
||||||
if ((idx
|
|
||||||
&& idx < 6
|
|
||||||
&& vim_strchr((char_u *)"DXOPQ",
|
|
||||||
fmt_ptr->prefix) != NULL)
|
|
||||||
|| (idx == 6
|
|
||||||
&& vim_strchr((char_u *)"OPQ",
|
|
||||||
fmt_ptr->prefix) == NULL))
|
|
||||||
{
|
|
||||||
sprintf((char *)errmsg,
|
|
||||||
_("E373: Unexpected %%%c in format string"), *efmp);
|
|
||||||
EMSG(errmsg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
fmt_ptr->addr[idx] = (char_u)++round;
|
|
||||||
*ptr++ = '\\';
|
|
||||||
*ptr++ = '(';
|
|
||||||
#ifdef BACKSLASH_IN_FILENAME
|
|
||||||
if (*efmp == 'f')
|
|
||||||
{
|
|
||||||
/* Also match "c:" in the file name, even when
|
|
||||||
* checking for a colon next: "%f:".
|
|
||||||
* "\%(\a:\)\=" */
|
|
||||||
STRCPY(ptr, "\\%(\\a:\\)\\=");
|
|
||||||
ptr += 10;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (*efmp == 'f' && efmp[1] != NUL)
|
|
||||||
{
|
|
||||||
if (efmp[1] != '\\' && efmp[1] != '%')
|
|
||||||
{
|
|
||||||
/* A file name may contain spaces, but this isn't
|
|
||||||
* in "\f". For "%f:%l:%m" there may be a ":" in
|
|
||||||
* the file name. Use ".\{-1,}x" instead (x is
|
|
||||||
* the next character), the requirement that :999:
|
|
||||||
* follows should work. */
|
|
||||||
STRCPY(ptr, ".\\{-1,}");
|
|
||||||
ptr += 7;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* File name followed by '\\' or '%': include as
|
|
||||||
* many file name chars as possible. */
|
|
||||||
STRCPY(ptr, "\\f\\+");
|
|
||||||
ptr += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
srcptr = (char_u *)fmt_pat[idx].pattern;
|
|
||||||
while ((*ptr = *srcptr++) != NUL)
|
|
||||||
++ptr;
|
|
||||||
}
|
|
||||||
*ptr++ = '\\';
|
|
||||||
*ptr++ = ')';
|
|
||||||
}
|
}
|
||||||
else if (*efmp == '*')
|
else if (*efmp == '*')
|
||||||
{
|
{
|
||||||
if (*++efmp == '[' || *efmp == '\\')
|
ptr = scanf_fmt_to_regpat(efm, len, &efmp, ptr, errmsg);
|
||||||
{
|
if (ptr == NULL)
|
||||||
if ((*ptr++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
|
|
||||||
{
|
|
||||||
if (efmp[1] == '^')
|
|
||||||
*ptr++ = *++efmp;
|
|
||||||
if (efmp < efm + len)
|
|
||||||
{
|
|
||||||
*ptr++ = *++efmp; /* could be ']' */
|
|
||||||
while (efmp < efm + len
|
|
||||||
&& (*ptr++ = *++efmp) != ']')
|
|
||||||
/* skip */;
|
|
||||||
if (efmp == efm + len)
|
|
||||||
{
|
|
||||||
EMSG(_("E374: Missing ] in format string"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (efmp < efm + len) /* %*\D, %*\s etc. */
|
|
||||||
*ptr++ = *++efmp;
|
|
||||||
*ptr++ = '\\';
|
|
||||||
*ptr++ = '+';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
|
|
||||||
sprintf((char *)errmsg,
|
|
||||||
_("E375: Unsupported %%%c in format string"), *efmp);
|
|
||||||
EMSG(errmsg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
|
else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
|
||||||
*ptr++ = *efmp; /* regexp magic characters */
|
*ptr++ = *efmp; /* regexp magic characters */
|
||||||
@@ -365,17 +433,8 @@ efm_to_regpat(
|
|||||||
fmt_ptr->conthere = TRUE;
|
fmt_ptr->conthere = TRUE;
|
||||||
else if (efmp == efm + 1) /* analyse prefix */
|
else if (efmp == efm + 1) /* analyse prefix */
|
||||||
{
|
{
|
||||||
if (vim_strchr((char_u *)"+-", *efmp) != NULL)
|
if (efm_analyze_prefix(&efmp, fmt_ptr, errmsg) == FAIL)
|
||||||
fmt_ptr->flags = *efmp++;
|
|
||||||
if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
|
|
||||||
fmt_ptr->prefix = *efmp;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf((char *)errmsg,
|
|
||||||
_("E376: Invalid %%%c in format string prefix"), *efmp);
|
|
||||||
EMSG(errmsg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -761,6 +761,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
10,
|
||||||
/**/
|
/**/
|
||||||
9,
|
9,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user