diff src/quickfix.c @ 27605:bf540a32439a v8.2.4329

patch 8.2.4329: no support for end line number and column in 'errorformat' Commit: https://github.com/vim/vim/commit/e023d499378942a6c3a3855cbe461ec2cb570f63 Author: haya14busa <haya14busa@gmail.com> Date: Tue Feb 8 18:09:29 2022 +0000 patch 8.2.4329: no support for end line number and column in 'errorformat' Problem: No support for end line number and column in 'errorformat'. Solution: Add %e and %k. (closes https://github.com/vim/vim/issues/9624)
author Bram Moolenaar <Bram@vim.org>
date Tue, 08 Feb 2022 19:15:03 +0100
parents ac75c145f0a9
children c1d1639b52dd
line wrap: on
line diff
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -118,7 +118,7 @@ struct qf_info_S
 static qf_info_T ql_info;	// global quickfix list
 static int_u last_qf_id = 0;	// Last used quickfix list id
 
-#define FMT_PATTERNS 11		// maximum number of % recognized
+#define FMT_PATTERNS 13		// maximum number of % recognized
 
 /*
  * Structure used to hold the info of one part of 'errorformat'
@@ -224,6 +224,9 @@ static bufref_T  qf_last_bufref = {NULL,
  */
 #define LINE_MAXLEN 4096
 
+/*
+ * Patterns used.  Keep in sync with qf_parse_fmt[].
+ */
 static struct fmtpattern
 {
     char_u	convchar;
@@ -231,16 +234,20 @@ static struct fmtpattern
 } fmt_pat[FMT_PATTERNS] =
     {
 	{'f', ".\\+"},	    // only used when at end
-	{'n', "\\d\\+"},
-	{'l', "\\d\\+"},
-	{'c', "\\d\\+"},
-	{'t', "."},
-	{'m', ".\\+"},
-	{'r', ".*"},
-	{'p', "[- 	.]*"},
-	{'v', "\\d\\+"},
-	{'s', ".\\+"},
-	{'o', ".\\+"}
+	{'n', "\\d\\+"},	// 1
+	{'l', "\\d\\+"},	// 2
+	{'e', "\\d\\+"},	// 3
+	{'c', "\\d\\+"},	// 4
+	{'k', "\\d\\+"},	// 5
+	{'t', "."},		// 6
+#define FMT_PATTERN_M 7
+	{'m', ".\\+"},		// 7
+#define FMT_PATTERN_R 8
+	{'r', ".*"},		// 8
+	{'p', "[- 	.]*"},	// 9
+	{'v', "\\d\\+"},	// 10
+	{'s', ".\\+"},		// 11
+	{'o', ".\\+"}		// 12
     };
 
 /*
@@ -265,9 +272,9 @@ efmpat_to_regpat(
 	semsg(_(e_too_many_chr_in_format_string), *efmpat);
 	return NULL;
     }
-    if ((idx && idx < 6
+    if ((idx && idx < FMT_PATTERN_R
 		&& vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
-	    || (idx == 6
+	    || (idx == FMT_PATTERN_R
 		&& vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
     {
 	semsg(_(e_unexpected_chr_in_format_str), *efmpat);
@@ -948,7 +955,7 @@ qf_parse_fmt_n(regmatch_T *rmp, int midx
 }
 
 /*
- * Parse the match for line number (%l') pattern in regmatch.
+ * Parse the match for line number ('%l') pattern in regmatch.
  * Return the matched value in "fields->lnum".
  */
     static int
@@ -961,6 +968,19 @@ qf_parse_fmt_l(regmatch_T *rmp, int midx
 }
 
 /*
+ * Parse the match for end line number ('%e') pattern in regmatch.
+ * Return the matched value in "fields->end_lnum".
+ */
+    static int
+qf_parse_fmt_e(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+    if (rmp->startp[midx] == NULL)
+	return QF_FAIL;
+    fields->end_lnum = atol((char *)rmp->startp[midx]);
+    return QF_OK;
+}
+
+/*
  * Parse the match for column number ('%c') pattern in regmatch.
  * Return the matched value in "fields->col".
  */
@@ -974,6 +994,19 @@ qf_parse_fmt_c(regmatch_T *rmp, int midx
 }
 
 /*
+ * Parse the match for end column number ('%k') pattern in regmatch.
+ * Return the matched value in "fields->end_col".
+ */
+    static int
+qf_parse_fmt_k(regmatch_T *rmp, int midx, qffields_T *fields)
+{
+    if (rmp->startp[midx] == NULL)
+	return QF_FAIL;
+    fields->end_col = (int)atol((char *)rmp->startp[midx]);
+    return QF_OK;
+}
+
+/*
  * Parse the match for error type ('%t') pattern in regmatch.
  * Return the matched value in "fields->type".
  */
@@ -1132,16 +1165,19 @@ qf_parse_fmt_o(regmatch_T *rmp, int midx
  * 'errorformat' format pattern parser functions.
  * The '%f' and '%r' formats are parsed differently from other formats.
  * See qf_parse_match() for details.
+ * Keep in sync with fmt_pat[].
  */
 static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
 {
-    NULL,
+    NULL, // %f
     qf_parse_fmt_n,
     qf_parse_fmt_l,
+    qf_parse_fmt_e,
     qf_parse_fmt_c,
+    qf_parse_fmt_k,
     qf_parse_fmt_t,
     qf_parse_fmt_m,
-    NULL,
+    NULL, // %r
     qf_parse_fmt_p,
     qf_parse_fmt_v,
     qf_parse_fmt_s,
@@ -1186,14 +1222,14 @@ qf_parse_match(
 	midx = (int)fmt_ptr->addr[i];
 	if (i == 0 && midx > 0)				// %f
 	    status = qf_parse_fmt_f(regmatch, midx, fields, idx);
-	else if (i == 5)
+	else if (i == FMT_PATTERN_M)
 	{
 	    if (fmt_ptr->flags == '+' && !qf_multiscan)	// %+
 		status = copy_nonerror_line(linebuf, linelen, fields);
 	    else if (midx > 0)				// %m
 		status = qf_parse_fmt_m(regmatch, midx, fields);
 	}
-	else if (i == 6 && midx > 0)			// %r
+	else if (i == FMT_PATTERN_R && midx > 0)	// %r
 	    status = qf_parse_fmt_r(regmatch, midx, tail);
 	else if (midx > 0)				// others
 	    status = (qf_parse_fmt[i])(regmatch, midx, fields);
@@ -1363,11 +1399,15 @@ qf_parse_multiline_pfx(
 
 	if (!qfprev->qf_lnum)
 	    qfprev->qf_lnum = fields->lnum;
+	if (!qfprev->qf_end_lnum)
+	    qfprev->qf_end_lnum = fields->end_lnum;
 	if (!qfprev->qf_col)
 	{
 	    qfprev->qf_col = fields->col;
 	    qfprev->qf_viscol = fields->use_viscol;
 	}
+	if (!qfprev->qf_end_col)
+	    qfprev->qf_end_col = fields->end_col;
 	if (!qfprev->qf_fnum)
 	    qfprev->qf_fnum = qf_get_fnum(qfl,
 		    qfl->qf_directory,