comparison src/quickfix.c @ 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 2ed1585c6467
children 710b1bb82f2c
comparison
equal deleted inserted replaced
13983:edbc72b9de83 13984:9b1dc5c2f460
226 {'s', ".\\+"}, 226 {'s', ".\\+"},
227 {'o', ".\\+"} 227 {'o', ".\\+"}
228 }; 228 };
229 229
230 /* 230 /*
231 * Convert an errorformat pattern to a regular expression pattern.
232 * See fmt_pat definition above for the list of supported patterns.
233 */
234 static char_u *
235 fmtpat_to_regpat(
236 char_u *efmp,
237 efm_T *fmt_ptr,
238 int idx,
239 int round,
240 char_u *ptr,
241 char_u *errmsg)
242 {
243 char_u *srcptr;
244
245 if (fmt_ptr->addr[idx])
246 {
247 /* Each errorformat pattern can occur only once */
248 sprintf((char *)errmsg,
249 _("E372: Too many %%%c in format string"), *efmp);
250 EMSG(errmsg);
251 return NULL;
252 }
253 if ((idx && idx < 6
254 && vim_strchr((char_u *)"DXOPQ", fmt_ptr->prefix) != NULL)
255 || (idx == 6
256 && vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL))
257 {
258 sprintf((char *)errmsg,
259 _("E373: Unexpected %%%c in format string"), *efmp);
260 EMSG(errmsg);
261 return NULL;
262 }
263 fmt_ptr->addr[idx] = (char_u)++round;
264 *ptr++ = '\\';
265 *ptr++ = '(';
266 #ifdef BACKSLASH_IN_FILENAME
267 if (*efmp == 'f')
268 {
269 /* Also match "c:" in the file name, even when
270 * checking for a colon next: "%f:".
271 * "\%(\a:\)\=" */
272 STRCPY(ptr, "\\%(\\a:\\)\\=");
273 ptr += 10;
274 }
275 #endif
276 if (*efmp == 'f' && efmp[1] != NUL)
277 {
278 if (efmp[1] != '\\' && efmp[1] != '%')
279 {
280 /* A file name may contain spaces, but this isn't
281 * in "\f". For "%f:%l:%m" there may be a ":" in
282 * the file name. Use ".\{-1,}x" instead (x is
283 * the next character), the requirement that :999:
284 * follows should work. */
285 STRCPY(ptr, ".\\{-1,}");
286 ptr += 7;
287 }
288 else
289 {
290 /* File name followed by '\\' or '%': include as
291 * many file name chars as possible. */
292 STRCPY(ptr, "\\f\\+");
293 ptr += 4;
294 }
295 }
296 else
297 {
298 srcptr = (char_u *)fmt_pat[idx].pattern;
299 while ((*ptr = *srcptr++) != NUL)
300 ++ptr;
301 }
302 *ptr++ = '\\';
303 *ptr++ = ')';
304
305 return ptr;
306 }
307
308 /*
309 * Convert a scanf like format in 'errorformat' to a regular expression.
310 */
311 static char_u *
312 scanf_fmt_to_regpat(
313 char_u *efm,
314 int len,
315 char_u **pefmp,
316 char_u *ptr,
317 char_u *errmsg)
318 {
319 char_u *efmp = *pefmp;
320
321 if (*++efmp == '[' || *efmp == '\\')
322 {
323 if ((*ptr++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
324 {
325 if (efmp[1] == '^')
326 *ptr++ = *++efmp;
327 if (efmp < efm + len)
328 {
329 *ptr++ = *++efmp; /* could be ']' */
330 while (efmp < efm + len
331 && (*ptr++ = *++efmp) != ']')
332 /* skip */;
333 if (efmp == efm + len)
334 {
335 EMSG(_("E374: Missing ] in format string"));
336 return NULL;
337 }
338 }
339 }
340 else if (efmp < efm + len) /* %*\D, %*\s etc. */
341 *ptr++ = *++efmp;
342 *ptr++ = '\\';
343 *ptr++ = '+';
344 }
345 else
346 {
347 /* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
348 sprintf((char *)errmsg,
349 _("E375: Unsupported %%%c in format string"), *efmp);
350 EMSG(errmsg);
351 return NULL;
352 }
353
354 *pefmp = efmp;
355
356 return ptr;
357 }
358
359 /*
360 * Analyze/parse an errorformat prefix.
361 */
362 static int
363 efm_analyze_prefix(char_u **pefmp, efm_T *fmt_ptr, char_u *errmsg)
364 {
365 char_u *efmp = *pefmp;
366
367 if (vim_strchr((char_u *)"+-", *efmp) != NULL)
368 fmt_ptr->flags = *efmp++;
369 if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
370 fmt_ptr->prefix = *efmp;
371 else
372 {
373 sprintf((char *)errmsg,
374 _("E376: Invalid %%%c in format string prefix"), *efmp);
375 EMSG(errmsg);
376 return FAIL;
377 }
378
379 *pefmp = efmp;
380
381 return OK;
382 }
383
384 /*
231 * Converts a 'errorformat' string to regular expression pattern 385 * Converts a 'errorformat' string to regular expression pattern
232 */ 386 */
233 static int 387 static int
234 efm_to_regpat( 388 efm_to_regpat(
235 char_u *efm, 389 char_u *efm,
236 int len, 390 int len,
237 efm_T *fmt_ptr, 391 efm_T *fmt_ptr,
238 char_u *regpat, 392 char_u *regpat,
239 char_u *errmsg) 393 char_u *errmsg)
240 { 394 {
241 char_u *ptr; 395 char_u *ptr;
242 char_u *efmp; 396 char_u *efmp;
243 char_u *srcptr;
244 int round; 397 int round;
245 int idx = 0; 398 int idx = 0;
246 399
247 /* 400 /*
248 * Build regexp pattern from current 'errorformat' option 401 * Build regexp pattern from current 'errorformat' option
258 for (idx = 0; idx < FMT_PATTERNS; ++idx) 411 for (idx = 0; idx < FMT_PATTERNS; ++idx)
259 if (fmt_pat[idx].convchar == *efmp) 412 if (fmt_pat[idx].convchar == *efmp)
260 break; 413 break;
261 if (idx < FMT_PATTERNS) 414 if (idx < FMT_PATTERNS)
262 { 415 {
263 if (fmt_ptr->addr[idx]) 416 ptr = fmtpat_to_regpat(efmp, fmt_ptr, idx, round, ptr,
264 { 417 errmsg);
265 sprintf((char *)errmsg, 418 if (ptr == NULL)
266 _("E372: Too many %%%c in format string"), *efmp);
267 EMSG(errmsg);
268 return -1; 419 return -1;
269 } 420 round++;
270 if ((idx
271 && idx < 6
272 && vim_strchr((char_u *)"DXOPQ",
273 fmt_ptr->prefix) != NULL)
274 || (idx == 6
275 && vim_strchr((char_u *)"OPQ",
276 fmt_ptr->prefix) == NULL))
277 {
278 sprintf((char *)errmsg,
279 _("E373: Unexpected %%%c in format string"), *efmp);
280 EMSG(errmsg);
281 return -1;
282 }
283 fmt_ptr->addr[idx] = (char_u)++round;
284 *ptr++ = '\\';
285 *ptr++ = '(';
286 #ifdef BACKSLASH_IN_FILENAME
287 if (*efmp == 'f')
288 {
289 /* Also match "c:" in the file name, even when
290 * checking for a colon next: "%f:".
291 * "\%(\a:\)\=" */
292 STRCPY(ptr, "\\%(\\a:\\)\\=");
293 ptr += 10;
294 }
295 #endif
296 if (*efmp == 'f' && efmp[1] != NUL)
297 {
298 if (efmp[1] != '\\' && efmp[1] != '%')
299 {
300 /* A file name may contain spaces, but this isn't
301 * in "\f". For "%f:%l:%m" there may be a ":" in
302 * the file name. Use ".\{-1,}x" instead (x is
303 * the next character), the requirement that :999:
304 * follows should work. */
305 STRCPY(ptr, ".\\{-1,}");
306 ptr += 7;
307 }
308 else
309 {
310 /* File name followed by '\\' or '%': include as
311 * many file name chars as possible. */
312 STRCPY(ptr, "\\f\\+");
313 ptr += 4;
314 }
315 }
316 else
317 {
318 srcptr = (char_u *)fmt_pat[idx].pattern;
319 while ((*ptr = *srcptr++) != NUL)
320 ++ptr;
321 }
322 *ptr++ = '\\';
323 *ptr++ = ')';
324 } 421 }
325 else if (*efmp == '*') 422 else if (*efmp == '*')
326 { 423 {
327 if (*++efmp == '[' || *efmp == '\\') 424 ptr = scanf_fmt_to_regpat(efm, len, &efmp, ptr, errmsg);
328 { 425 if (ptr == NULL)
329 if ((*ptr++ = *efmp) == '[') /* %*[^a-z0-9] etc. */
330 {
331 if (efmp[1] == '^')
332 *ptr++ = *++efmp;
333 if (efmp < efm + len)
334 {
335 *ptr++ = *++efmp; /* could be ']' */
336 while (efmp < efm + len
337 && (*ptr++ = *++efmp) != ']')
338 /* skip */;
339 if (efmp == efm + len)
340 {
341 EMSG(_("E374: Missing ] in format string"));
342 return -1;
343 }
344 }
345 }
346 else if (efmp < efm + len) /* %*\D, %*\s etc. */
347 *ptr++ = *++efmp;
348 *ptr++ = '\\';
349 *ptr++ = '+';
350 }
351 else
352 {
353 /* TODO: scanf()-like: %*ud, %*3c, %*f, ... ? */
354 sprintf((char *)errmsg,
355 _("E375: Unsupported %%%c in format string"), *efmp);
356 EMSG(errmsg);
357 return -1; 426 return -1;
358 }
359 } 427 }
360 else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) 428 else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL)
361 *ptr++ = *efmp; /* regexp magic characters */ 429 *ptr++ = *efmp; /* regexp magic characters */
362 else if (*efmp == '#') 430 else if (*efmp == '#')
363 *ptr++ = '*'; 431 *ptr++ = '*';
364 else if (*efmp == '>') 432 else if (*efmp == '>')
365 fmt_ptr->conthere = TRUE; 433 fmt_ptr->conthere = TRUE;
366 else if (efmp == efm + 1) /* analyse prefix */ 434 else if (efmp == efm + 1) /* analyse prefix */
367 { 435 {
368 if (vim_strchr((char_u *)"+-", *efmp) != NULL) 436 if (efm_analyze_prefix(&efmp, fmt_ptr, errmsg) == FAIL)
369 fmt_ptr->flags = *efmp++;
370 if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL)
371 fmt_ptr->prefix = *efmp;
372 else
373 {
374 sprintf((char *)errmsg,
375 _("E376: Invalid %%%c in format string prefix"), *efmp);
376 EMSG(errmsg);
377 return -1; 437 return -1;
378 }
379 } 438 }
380 else 439 else
381 { 440 {
382 sprintf((char *)errmsg, 441 sprintf((char *)errmsg,
383 _("E377: Invalid %%%c in format string"), *efmp); 442 _("E377: Invalid %%%c in format string"), *efmp);