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:
Jan Edmund Lazo
2019-09-24 04:22:54 -04:00
parent 30ae60e7ca
commit 0253f0cd92

View File

@@ -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) {