mirror of
https://github.com/neovim/neovim.git
synced 2025-09-18 09:18:19 +00:00
vim-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 vim/vim#2924)
6bff719f7e
This commit is contained in:
@@ -264,42 +264,35 @@ static struct fmtpattern
|
|||||||
{ 'o', ".\\+" }
|
{ 'o', ".\\+" }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converts a 'errorformat' string to regular expression pattern
|
// Convert an errorformat pattern to a regular expression pattern.
|
||||||
static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
|
// See fmt_pat definition above for the list of supported patterns.
|
||||||
char_u *regpat, char_u *errmsg)
|
static char_u *fmtpat_to_regpat(
|
||||||
|
const char_u *efmp,
|
||||||
|
efm_T *fmt_ptr,
|
||||||
|
int idx,
|
||||||
|
int round,
|
||||||
|
char_u *ptr,
|
||||||
|
char_u *errmsg,
|
||||||
|
size_t errmsglen)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
// Build regexp pattern from current 'errorformat' option
|
|
||||||
char_u *ptr = regpat;
|
|
||||||
*ptr++ = '^';
|
|
||||||
int round = 0;
|
|
||||||
for (char_u *efmp = efm; efmp < efm + len; efmp++) {
|
|
||||||
if (*efmp == '%') {
|
|
||||||
efmp++;
|
|
||||||
int idx;
|
|
||||||
for (idx = 0; idx < FMT_PATTERNS; idx++) {
|
|
||||||
if (fmt_pat[idx].convchar == *efmp) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (idx < FMT_PATTERNS) {
|
|
||||||
if (fmt_ptr->addr[idx]) {
|
if (fmt_ptr->addr[idx]) {
|
||||||
snprintf((char *)errmsg, CMDBUFFSIZE + 1,
|
// Each errorformat pattern can occur only once
|
||||||
|
snprintf((char *)errmsg, errmsglen,
|
||||||
_("E372: Too many %%%c in format string"), *efmp);
|
_("E372: Too many %%%c in format string"), *efmp);
|
||||||
EMSG(errmsg);
|
EMSG(errmsg);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((idx
|
if ((idx && idx < 6
|
||||||
&& idx < 6
|
|
||||||
&& vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
|
&& vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
|
||||||
|| (idx == 6
|
|| (idx == 6
|
||||||
&& vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL)) {
|
&& vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL)) {
|
||||||
snprintf((char *)errmsg, CMDBUFFSIZE + 1,
|
snprintf((char *)errmsg, errmsglen,
|
||||||
_("E373: Unexpected %%%c in format string"), *efmp);
|
_("E373: Unexpected %%%c in format string"), *efmp);
|
||||||
EMSG(errmsg);
|
EMSG(errmsg);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
round++;
|
fmt_ptr->addr[idx] = (char_u)++round;
|
||||||
fmt_ptr->addr[idx] = (char_u)round;
|
|
||||||
*ptr++ = '\\';
|
*ptr++ = '\\';
|
||||||
*ptr++ = '(';
|
*ptr++ = '(';
|
||||||
#ifdef BACKSLASH_IN_FILENAME
|
#ifdef BACKSLASH_IN_FILENAME
|
||||||
@@ -334,37 +327,107 @@ static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
|
|||||||
}
|
}
|
||||||
*ptr++ = '\\';
|
*ptr++ = '\\';
|
||||||
*ptr++ = ')';
|
*ptr++ = ')';
|
||||||
} else if (*efmp == '*') {
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a scanf like format in 'errorformat' to a regular expression.
|
||||||
|
static char_u *scanf_fmt_to_regpat(
|
||||||
|
const char_u *efm,
|
||||||
|
int len,
|
||||||
|
const char_u **pefmp,
|
||||||
|
char_u *ptr,
|
||||||
|
char_u *errmsg,
|
||||||
|
size_t errmsglen)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
const char_u *efmp = *pefmp;
|
||||||
|
|
||||||
if (*++efmp == '[' || *efmp == '\\') {
|
if (*++efmp == '[' || *efmp == '\\') {
|
||||||
if ((*ptr++ = *efmp) == '[') { // %*[^a-z0-9] etc.
|
if ((*ptr++ = *efmp) == '[') { // %*[^a-z0-9] etc.
|
||||||
if (efmp[1] == '^') {
|
if (efmp[1] == '^') {
|
||||||
*ptr++ = *++efmp;
|
*ptr++ = *++efmp;
|
||||||
}
|
}
|
||||||
if (efmp < efm + len) {
|
if (efmp < efm + len) {
|
||||||
efmp++;
|
*ptr++ = *++efmp; // could be ']'
|
||||||
*ptr++ = *efmp; // could be ']'
|
while (efmp < efm + len && (*ptr++ = *++efmp) != ']') {
|
||||||
while (efmp < efm + len) {
|
|
||||||
efmp++;
|
|
||||||
if ((*ptr++ = *efmp) == ']') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (efmp == efm + len) {
|
if (efmp == efm + len) {
|
||||||
EMSG(_("E374: Missing ] in format string"));
|
EMSG(_("E374: Missing ] in format string"));
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (efmp < efm + len) { // %*\D, %*\s etc.
|
} else if (efmp < efm + len) { // %*\D, %*\s etc.
|
||||||
efmp++;
|
*ptr++ = *++efmp;
|
||||||
*ptr++ = *efmp;
|
|
||||||
}
|
}
|
||||||
*ptr++ = '\\';
|
*ptr++ = '\\';
|
||||||
*ptr++ = '+';
|
*ptr++ = '+';
|
||||||
} else {
|
} else {
|
||||||
// TODO(vim): scanf()-like: %*ud, %*3c, %*f, ... ?
|
// TODO(vim): scanf()-like: %*ud, %*3c, %*f, ... ?
|
||||||
snprintf((char *)errmsg, CMDBUFFSIZE + 1,
|
snprintf((char *)errmsg, errmsglen,
|
||||||
_("E375: Unsupported %%%c in format string"), *efmp);
|
_("E375: Unsupported %%%c in format string"), *efmp);
|
||||||
EMSG(errmsg);
|
EMSG(errmsg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pefmp = efmp;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Analyze/parse an errorformat prefix.
|
||||||
|
static int efm_analyze_prefix(const char_u **pefmp, efm_T *fmt_ptr,
|
||||||
|
char_u *errmsg, size_t errmsglen)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
const 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 {
|
||||||
|
snprintf((char *)errmsg, errmsglen,
|
||||||
|
_("E376: Invalid %%%c in format string prefix"), *efmp);
|
||||||
|
EMSG(errmsg);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pefmp = efmp;
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Converts a 'errorformat' string to regular expression pattern
|
||||||
|
static int efm_to_regpat(const char_u *efm, int len, efm_T *fmt_ptr,
|
||||||
|
char_u *regpat, char_u *errmsg, size_t errmsglen)
|
||||||
|
FUNC_ATTR_NONNULL_ALL
|
||||||
|
{
|
||||||
|
// Build regexp pattern from current 'errorformat' option
|
||||||
|
char_u *ptr = regpat;
|
||||||
|
*ptr++ = '^';
|
||||||
|
int round = 0;
|
||||||
|
for (const char_u *efmp = efm; efmp < efm + len; efmp++) {
|
||||||
|
if (*efmp == '%') {
|
||||||
|
efmp++;
|
||||||
|
int idx;
|
||||||
|
for (idx = 0; idx < FMT_PATTERNS; idx++) {
|
||||||
|
if (fmt_pat[idx].convchar == *efmp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (idx < FMT_PATTERNS) {
|
||||||
|
ptr = fmtpat_to_regpat(efmp, fmt_ptr, idx, round, ptr,
|
||||||
|
errmsg, errmsglen);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
round++;
|
||||||
|
} else if (*efmp == '*') {
|
||||||
|
ptr = scanf_fmt_to_regpat(efm, len, &efmp, ptr, errmsg, errmsglen);
|
||||||
|
if (ptr == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) {
|
} else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) {
|
||||||
@@ -374,15 +437,7 @@ static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
|
|||||||
} else if (*efmp == '>') {
|
} else if (*efmp == '>') {
|
||||||
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, errmsglen) == FAIL) {
|
||||||
fmt_ptr->flags = *efmp++;
|
|
||||||
}
|
|
||||||
if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL) {
|
|
||||||
fmt_ptr->prefix = *efmp;
|
|
||||||
} else {
|
|
||||||
snprintf((char *)errmsg, CMDBUFFSIZE + 1,
|
|
||||||
_("E376: Invalid %%%c in format string prefix"), *efmp);
|
|
||||||
EMSG(errmsg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -461,7 +516,7 @@ static efm_T * parse_efm_option(char_u *efm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (efm_to_regpat(efm, len, fmt_ptr, fmtstr, errmsg) == -1) {
|
if (efm_to_regpat(efm, len, fmt_ptr, fmtstr, errmsg, errmsglen) == -1) {
|
||||||
goto parse_efm_error;
|
goto parse_efm_error;
|
||||||
}
|
}
|
||||||
if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL) {
|
if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL) {
|
||||||
|
Reference in New Issue
Block a user