@@ -118,7 +118,7 @@ struct qf_info_S
118118static qf_info_T ql_info ; // global quickfix list
119119static int_u last_qf_id = 0 ; // Last used quickfix list id
120120
121- #define FMT_PATTERNS 11 // maximum number of % recognized
121+ #define FMT_PATTERNS 13 // maximum number of % recognized
122122
123123/*
124124 * Structure used to hold the info of one part of 'errorformat'
@@ -224,23 +224,30 @@ static bufref_T qf_last_bufref = {NULL, 0, 0};
224224 */
225225#define LINE_MAXLEN 4096
226226
227+ /*
228+ * Patterns used. Keep in sync with qf_parse_fmt[].
229+ */
227230static struct fmtpattern
228231{
229232 char_u convchar ;
230233 char * pattern ;
231234} fmt_pat [FMT_PATTERNS ] =
232235 {
233236 {'f' , ".\\+" }, // only used when at end
234- {'n' , "\\d\\+" },
235- {'l' , "\\d\\+" },
236- {'c' , "\\d\\+" },
237- {'t' , "." },
238- {'m' , ".\\+" },
239- {'r' , ".*" },
240- {'p' , "[- .]*" },
241- {'v' , "\\d\\+" },
242- {'s' , ".\\+" },
243- {'o' , ".\\+" }
237+ {'n' , "\\d\\+" }, // 1
238+ {'l' , "\\d\\+" }, // 2
239+ {'e' , "\\d\\+" }, // 3
240+ {'c' , "\\d\\+" }, // 4
241+ {'k' , "\\d\\+" }, // 5
242+ {'t' , "." }, // 6
243+ #define FMT_PATTERN_M 7
244+ {'m' , ".\\+" }, // 7
245+ #define FMT_PATTERN_R 8
246+ {'r' , ".*" }, // 8
247+ {'p' , "[- .]*" }, // 9
248+ {'v' , "\\d\\+" }, // 10
249+ {'s' , ".\\+" }, // 11
250+ {'o' , ".\\+" } // 12
244251 };
245252
246253/*
@@ -265,9 +272,9 @@ efmpat_to_regpat(
265272 semsg (_ (e_too_many_chr_in_format_string ), * efmpat );
266273 return NULL ;
267274 }
268- if ((idx && idx < 6
275+ if ((idx && idx < FMT_PATTERN_R
269276 && vim_strchr ((char_u * )"DXOPQ" , efminfo -> prefix ) != NULL )
270- || (idx == 6
277+ || (idx == FMT_PATTERN_R
271278 && vim_strchr ((char_u * )"OPQ" , efminfo -> prefix ) == NULL ))
272279 {
273280 semsg (_ (e_unexpected_chr_in_format_str ), * efmpat );
@@ -948,7 +955,7 @@ qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields)
948955}
949956
950957/*
951- * Parse the match for line number (%l') pattern in regmatch.
958+ * Parse the match for line number (' %l') pattern in regmatch.
952959 * Return the matched value in "fields->lnum".
953960 */
954961 static int
@@ -960,6 +967,19 @@ qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
960967 return QF_OK ;
961968}
962969
970+ /*
971+ * Parse the match for end line number ('%e') pattern in regmatch.
972+ * Return the matched value in "fields->end_lnum".
973+ */
974+ static int
975+ qf_parse_fmt_e (regmatch_T * rmp , int midx , qffields_T * fields )
976+ {
977+ if (rmp -> startp [midx ] == NULL )
978+ return QF_FAIL ;
979+ fields -> end_lnum = atol ((char * )rmp -> startp [midx ]);
980+ return QF_OK ;
981+ }
982+
963983/*
964984 * Parse the match for column number ('%c') pattern in regmatch.
965985 * Return the matched value in "fields->col".
@@ -973,6 +993,19 @@ qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
973993 return QF_OK ;
974994}
975995
996+ /*
997+ * Parse the match for end column number ('%k') pattern in regmatch.
998+ * Return the matched value in "fields->end_col".
999+ */
1000+ static int
1001+ qf_parse_fmt_k (regmatch_T * rmp , int midx , qffields_T * fields )
1002+ {
1003+ if (rmp -> startp [midx ] == NULL )
1004+ return QF_FAIL ;
1005+ fields -> end_col = (int )atol ((char * )rmp -> startp [midx ]);
1006+ return QF_OK ;
1007+ }
1008+
9761009/*
9771010 * Parse the match for error type ('%t') pattern in regmatch.
9781011 * Return the matched value in "fields->type".
@@ -1132,16 +1165,19 @@ qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields)
11321165 * 'errorformat' format pattern parser functions.
11331166 * The '%f' and '%r' formats are parsed differently from other formats.
11341167 * See qf_parse_match() for details.
1168+ * Keep in sync with fmt_pat[].
11351169 */
11361170static int (* qf_parse_fmt [FMT_PATTERNS ])(regmatch_T * , int , qffields_T * ) =
11371171{
1138- NULL ,
1172+ NULL , // %f
11391173 qf_parse_fmt_n ,
11401174 qf_parse_fmt_l ,
1175+ qf_parse_fmt_e ,
11411176 qf_parse_fmt_c ,
1177+ qf_parse_fmt_k ,
11421178 qf_parse_fmt_t ,
11431179 qf_parse_fmt_m ,
1144- NULL ,
1180+ NULL , // %r
11451181 qf_parse_fmt_p ,
11461182 qf_parse_fmt_v ,
11471183 qf_parse_fmt_s ,
@@ -1186,14 +1222,14 @@ qf_parse_match(
11861222 midx = (int )fmt_ptr -> addr [i ];
11871223 if (i == 0 && midx > 0 ) // %f
11881224 status = qf_parse_fmt_f (regmatch , midx , fields , idx );
1189- else if (i == 5 )
1225+ else if (i == FMT_PATTERN_M )
11901226 {
11911227 if (fmt_ptr -> flags == '+' && !qf_multiscan ) // %+
11921228 status = copy_nonerror_line (linebuf , linelen , fields );
11931229 else if (midx > 0 ) // %m
11941230 status = qf_parse_fmt_m (regmatch , midx , fields );
11951231 }
1196- else if (i == 6 && midx > 0 ) // %r
1232+ else if (i == FMT_PATTERN_R && midx > 0 ) // %r
11971233 status = qf_parse_fmt_r (regmatch , midx , tail );
11981234 else if (midx > 0 ) // others
11991235 status = (qf_parse_fmt [i ])(regmatch , midx , fields );
@@ -1363,11 +1399,15 @@ qf_parse_multiline_pfx(
13631399
13641400 if (!qfprev -> qf_lnum )
13651401 qfprev -> qf_lnum = fields -> lnum ;
1402+ if (!qfprev -> qf_end_lnum )
1403+ qfprev -> qf_end_lnum = fields -> end_lnum ;
13661404 if (!qfprev -> qf_col )
13671405 {
13681406 qfprev -> qf_col = fields -> col ;
13691407 qfprev -> qf_viscol = fields -> use_viscol ;
13701408 }
1409+ if (!qfprev -> qf_end_col )
1410+ qfprev -> qf_end_col = fields -> end_col ;
13711411 if (!qfprev -> qf_fnum )
13721412 qfprev -> qf_fnum = qf_get_fnum (qfl ,
13731413 qfl -> qf_directory ,
0 commit comments