changeset 13984:9b1dc5c2f460 v8.1.0010

patch 8.1.0010: efm_to_regpat() is too long commit https://github.com/vim/vim/commit/6bff719f7e472e918c60aa336de03e799b806c4f Author: Bram Moolenaar <Bram@vim.org> Date: Sun May 20 15:41:17 2018 +0200 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 https://github.com/vim/vim/issues/2924)
author Christian Brabandt <cb@256bit.org>
date Sun, 20 May 2018 15:45:04 +0200
parents edbc72b9de83
children 3c3c934eccc0
files src/quickfix.c src/version.c
diffstat 2 files changed, 164 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -228,19 +228,172 @@ static struct fmtpattern
     };
 
 /*
+ * 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
  */
     static int
 efm_to_regpat(
 	char_u	*efm,
-	int		len,
+	int	len,
 	efm_T	*fmt_ptr,
 	char_u	*regpat,
 	char_u	*errmsg)
 {
     char_u	*ptr;
     char_u	*efmp;
-    char_u	*srcptr;
     int		round;
     int		idx = 0;
 
@@ -260,102 +413,17 @@ efm_to_regpat(
 		    break;
 	    if (idx < FMT_PATTERNS)
 	    {
-		if (fmt_ptr->addr[idx])
-		{
-		    sprintf((char *)errmsg,
-			    _("E372: Too many %%%c in format string"), *efmp);
-		    EMSG(errmsg);
-		    return -1;
-		}
-		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);
+		ptr = fmtpat_to_regpat(efmp, fmt_ptr, idx, round, ptr,
+								errmsg);
+		if (ptr == NULL)
 		    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++ = ')';
+		round++;
 	    }
 	    else if (*efmp == '*')
 	    {
-		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 -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);
+		ptr = scanf_fmt_to_regpat(efm, len, &efmp, ptr, errmsg);
+		if (ptr == NULL)
 		    return -1;
-		}
 	    }
 	    else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
 		*ptr++ = *efmp;		/* regexp magic characters */
@@ -365,17 +433,8 @@ efm_to_regpat(
 		fmt_ptr->conthere = TRUE;
 	    else if (efmp == efm + 1)		/* analyse prefix */
 	    {
-		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);
+		if (efm_analyze_prefix(&efmp, fmt_ptr, errmsg) == FAIL)
 		    return -1;
-		}
 	    }
 	    else
 	    {
--- a/src/version.c
+++ b/src/version.c
@@ -762,6 +762,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    10,
+/**/
     9,
 /**/
     8,