comparison 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
comparison
equal deleted inserted replaced
27604:4f782c34c224 27605:bf540a32439a
116 }; 116 };
117 117
118 static qf_info_T ql_info; // global quickfix list 118 static qf_info_T ql_info; // global quickfix list
119 static int_u last_qf_id = 0; // Last used quickfix list id 119 static int_u last_qf_id = 0; // Last used quickfix list id
120 120
121 #define FMT_PATTERNS 11 // maximum number of % recognized 121 #define FMT_PATTERNS 13 // maximum number of % recognized
122 122
123 /* 123 /*
124 * Structure used to hold the info of one part of 'errorformat' 124 * Structure used to hold the info of one part of 'errorformat'
125 */ 125 */
126 typedef struct efm_S efm_T; 126 typedef struct efm_S efm_T;
222 /* 222 /*
223 * Maximum number of bytes allowed per line while reading a errorfile. 223 * Maximum number of bytes allowed per line while reading a errorfile.
224 */ 224 */
225 #define LINE_MAXLEN 4096 225 #define LINE_MAXLEN 4096
226 226
227 /*
228 * Patterns used. Keep in sync with qf_parse_fmt[].
229 */
227 static struct fmtpattern 230 static struct fmtpattern
228 { 231 {
229 char_u convchar; 232 char_u convchar;
230 char *pattern; 233 char *pattern;
231 } fmt_pat[FMT_PATTERNS] = 234 } fmt_pat[FMT_PATTERNS] =
232 { 235 {
233 {'f', ".\\+"}, // only used when at end 236 {'f', ".\\+"}, // only used when at end
234 {'n', "\\d\\+"}, 237 {'n', "\\d\\+"}, // 1
235 {'l', "\\d\\+"}, 238 {'l', "\\d\\+"}, // 2
236 {'c', "\\d\\+"}, 239 {'e', "\\d\\+"}, // 3
237 {'t', "."}, 240 {'c', "\\d\\+"}, // 4
238 {'m', ".\\+"}, 241 {'k', "\\d\\+"}, // 5
239 {'r', ".*"}, 242 {'t', "."}, // 6
240 {'p', "[- .]*"}, 243 #define FMT_PATTERN_M 7
241 {'v', "\\d\\+"}, 244 {'m', ".\\+"}, // 7
242 {'s', ".\\+"}, 245 #define FMT_PATTERN_R 8
243 {'o', ".\\+"} 246 {'r', ".*"}, // 8
247 {'p', "[- .]*"}, // 9
248 {'v', "\\d\\+"}, // 10
249 {'s', ".\\+"}, // 11
250 {'o', ".\\+"} // 12
244 }; 251 };
245 252
246 /* 253 /*
247 * Convert an errorformat pattern to a regular expression pattern. 254 * Convert an errorformat pattern to a regular expression pattern.
248 * See fmt_pat definition above for the list of supported patterns. The 255 * See fmt_pat definition above for the list of supported patterns. The
263 { 270 {
264 // Each errorformat pattern can occur only once 271 // Each errorformat pattern can occur only once
265 semsg(_(e_too_many_chr_in_format_string), *efmpat); 272 semsg(_(e_too_many_chr_in_format_string), *efmpat);
266 return NULL; 273 return NULL;
267 } 274 }
268 if ((idx && idx < 6 275 if ((idx && idx < FMT_PATTERN_R
269 && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL) 276 && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL)
270 || (idx == 6 277 || (idx == FMT_PATTERN_R
271 && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL)) 278 && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL))
272 { 279 {
273 semsg(_(e_unexpected_chr_in_format_str), *efmpat); 280 semsg(_(e_unexpected_chr_in_format_str), *efmpat);
274 return NULL; 281 return NULL;
275 } 282 }
946 fields->enr = (int)atol((char *)rmp->startp[midx]); 953 fields->enr = (int)atol((char *)rmp->startp[midx]);
947 return QF_OK; 954 return QF_OK;
948 } 955 }
949 956
950 /* 957 /*
951 * Parse the match for line number (%l') pattern in regmatch. 958 * Parse the match for line number ('%l') pattern in regmatch.
952 * Return the matched value in "fields->lnum". 959 * Return the matched value in "fields->lnum".
953 */ 960 */
954 static int 961 static int
955 qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields) 962 qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields)
956 { 963 {
959 fields->lnum = atol((char *)rmp->startp[midx]); 966 fields->lnum = atol((char *)rmp->startp[midx]);
960 return QF_OK; 967 return QF_OK;
961 } 968 }
962 969
963 /* 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
983 /*
964 * Parse the match for column number ('%c') pattern in regmatch. 984 * Parse the match for column number ('%c') pattern in regmatch.
965 * Return the matched value in "fields->col". 985 * Return the matched value in "fields->col".
966 */ 986 */
967 static int 987 static int
968 qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields) 988 qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields)
969 { 989 {
970 if (rmp->startp[midx] == NULL) 990 if (rmp->startp[midx] == NULL)
971 return QF_FAIL; 991 return QF_FAIL;
972 fields->col = (int)atol((char *)rmp->startp[midx]); 992 fields->col = (int)atol((char *)rmp->startp[midx]);
993 return QF_OK;
994 }
995
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]);
973 return QF_OK; 1006 return QF_OK;
974 } 1007 }
975 1008
976 /* 1009 /*
977 * Parse the match for error type ('%t') pattern in regmatch. 1010 * Parse the match for error type ('%t') pattern in regmatch.
1130 1163
1131 /* 1164 /*
1132 * 'errorformat' format pattern parser functions. 1165 * 'errorformat' format pattern parser functions.
1133 * The '%f' and '%r' formats are parsed differently from other formats. 1166 * The '%f' and '%r' formats are parsed differently from other formats.
1134 * See qf_parse_match() for details. 1167 * See qf_parse_match() for details.
1168 * Keep in sync with fmt_pat[].
1135 */ 1169 */
1136 static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = 1170 static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) =
1137 { 1171 {
1138 NULL, 1172 NULL, // %f
1139 qf_parse_fmt_n, 1173 qf_parse_fmt_n,
1140 qf_parse_fmt_l, 1174 qf_parse_fmt_l,
1175 qf_parse_fmt_e,
1141 qf_parse_fmt_c, 1176 qf_parse_fmt_c,
1177 qf_parse_fmt_k,
1142 qf_parse_fmt_t, 1178 qf_parse_fmt_t,
1143 qf_parse_fmt_m, 1179 qf_parse_fmt_m,
1144 NULL, 1180 NULL, // %r
1145 qf_parse_fmt_p, 1181 qf_parse_fmt_p,
1146 qf_parse_fmt_v, 1182 qf_parse_fmt_v,
1147 qf_parse_fmt_s, 1183 qf_parse_fmt_s,
1148 qf_parse_fmt_o 1184 qf_parse_fmt_o
1149 }; 1185 };
1184 { 1220 {
1185 status = QF_OK; 1221 status = QF_OK;
1186 midx = (int)fmt_ptr->addr[i]; 1222 midx = (int)fmt_ptr->addr[i];
1187 if (i == 0 && midx > 0) // %f 1223 if (i == 0 && midx > 0) // %f
1188 status = qf_parse_fmt_f(regmatch, midx, fields, idx); 1224 status = qf_parse_fmt_f(regmatch, midx, fields, idx);
1189 else if (i == 5) 1225 else if (i == FMT_PATTERN_M)
1190 { 1226 {
1191 if (fmt_ptr->flags == '+' && !qf_multiscan) // %+ 1227 if (fmt_ptr->flags == '+' && !qf_multiscan) // %+
1192 status = copy_nonerror_line(linebuf, linelen, fields); 1228 status = copy_nonerror_line(linebuf, linelen, fields);
1193 else if (midx > 0) // %m 1229 else if (midx > 0) // %m
1194 status = qf_parse_fmt_m(regmatch, midx, fields); 1230 status = qf_parse_fmt_m(regmatch, midx, fields);
1195 } 1231 }
1196 else if (i == 6 && midx > 0) // %r 1232 else if (i == FMT_PATTERN_R && midx > 0) // %r
1197 status = qf_parse_fmt_r(regmatch, midx, tail); 1233 status = qf_parse_fmt_r(regmatch, midx, tail);
1198 else if (midx > 0) // others 1234 else if (midx > 0) // others
1199 status = (qf_parse_fmt[i])(regmatch, midx, fields); 1235 status = (qf_parse_fmt[i])(regmatch, midx, fields);
1200 1236
1201 if (status != QF_OK) 1237 if (status != QF_OK)
1361 // only printable chars allowed 1397 // only printable chars allowed
1362 qfprev->qf_type = fields->type; 1398 qfprev->qf_type = fields->type;
1363 1399
1364 if (!qfprev->qf_lnum) 1400 if (!qfprev->qf_lnum)
1365 qfprev->qf_lnum = fields->lnum; 1401 qfprev->qf_lnum = fields->lnum;
1402 if (!qfprev->qf_end_lnum)
1403 qfprev->qf_end_lnum = fields->end_lnum;
1366 if (!qfprev->qf_col) 1404 if (!qfprev->qf_col)
1367 { 1405 {
1368 qfprev->qf_col = fields->col; 1406 qfprev->qf_col = fields->col;
1369 qfprev->qf_viscol = fields->use_viscol; 1407 qfprev->qf_viscol = fields->use_viscol;
1370 } 1408 }
1409 if (!qfprev->qf_end_col)
1410 qfprev->qf_end_col = fields->end_col;
1371 if (!qfprev->qf_fnum) 1411 if (!qfprev->qf_fnum)
1372 qfprev->qf_fnum = qf_get_fnum(qfl, 1412 qfprev->qf_fnum = qf_get_fnum(qfl,
1373 qfl->qf_directory, 1413 qfl->qf_directory,
1374 *fields->namebuf || qfl->qf_directory != NULL 1414 *fields->namebuf || qfl->qf_directory != NULL
1375 ? fields->namebuf 1415 ? fields->namebuf