Mercurial > vim
comparison src/quickfix.c @ 9033:0536d1469b67 v7.4.1802
commit https://github.com/vim/vim/commit/6be8c8e165204b8aa4eeb8a52be87a58d8b41b9e
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Apr 30 13:17:09 2016 +0200
patch 7.4.1802
Problem: Quickfix doesn't handle long lines well, they are split.
Solution: Drop characters after a limit. (Anton Lindqvist)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 30 Apr 2016 13:30:05 +0200 |
parents | 25c2031e9f9f |
children | 19d2dfb3f5e2 |
comparison
equal
deleted
inserted
replaced
9032:7dd86887e8f1 | 9033:0536d1469b67 |
---|---|
173 (linenr_T)0, (linenr_T)0, | 173 (linenr_T)0, (linenr_T)0, |
174 qf_title); | 174 qf_title); |
175 } | 175 } |
176 | 176 |
177 /* | 177 /* |
178 * Maximum number of bytes allowed per line while reading a errorfile. | |
179 */ | |
180 #define LINE_MAXLEN 4096 | |
181 | |
182 /* | |
178 * Read the errorfile "efile" into memory, line by line, building the error | 183 * Read the errorfile "efile" into memory, line by line, building the error |
179 * list. | 184 * list. |
180 * Alternative: when "efile" is null read errors from buffer "buf". | 185 * Alternative: when "efile" is null read errors from buffer "buf". |
181 * Always use 'errorformat' from "buf" if there is a local value. | 186 * Always use 'errorformat' from "buf" if there is a local value. |
182 * Then "lnumfirst" and "lnumlast" specify the range of lines to use. | 187 * Then "lnumfirst" and "lnumlast" specify the range of lines to use. |
195 linenr_T lnumlast, /* last line number to use */ | 200 linenr_T lnumlast, /* last line number to use */ |
196 char_u *qf_title) | 201 char_u *qf_title) |
197 { | 202 { |
198 char_u *namebuf; | 203 char_u *namebuf; |
199 char_u *errmsg; | 204 char_u *errmsg; |
205 int errmsglen; | |
200 char_u *pattern; | 206 char_u *pattern; |
201 char_u *fmtstr = NULL; | 207 char_u *fmtstr = NULL; |
208 char_u *growbuf = NULL; | |
209 int growbuflen; | |
210 int growbufsiz; | |
211 char_u *linebuf; | |
212 int linelen; | |
213 int discard; | |
202 int col = 0; | 214 int col = 0; |
203 char_u use_viscol = FALSE; | 215 char_u use_viscol = FALSE; |
204 int type = 0; | 216 int type = 0; |
205 int valid; | 217 int valid; |
206 linenr_T buflnum = lnumfirst; | 218 linenr_T buflnum = lnumfirst; |
225 int multiscan = FALSE; | 237 int multiscan = FALSE; |
226 int retval = -1; /* default: return error flag */ | 238 int retval = -1; /* default: return error flag */ |
227 char_u *directory = NULL; | 239 char_u *directory = NULL; |
228 char_u *currfile = NULL; | 240 char_u *currfile = NULL; |
229 char_u *tail = NULL; | 241 char_u *tail = NULL; |
242 char_u *p_buf = NULL; | |
230 char_u *p_str = NULL; | 243 char_u *p_str = NULL; |
231 listitem_T *p_li = NULL; | 244 listitem_T *p_li = NULL; |
232 struct dir_stack_T *file_stack = NULL; | 245 struct dir_stack_T *file_stack = NULL; |
233 regmatch_T regmatch; | 246 regmatch_T regmatch; |
234 static struct fmtpattern | 247 static struct fmtpattern |
248 {'v', "\\d\\+"}, | 261 {'v', "\\d\\+"}, |
249 {'s', ".\\+"} | 262 {'s', ".\\+"} |
250 }; | 263 }; |
251 | 264 |
252 namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf); | 265 namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf); |
253 errmsg = alloc_id(CMDBUFFSIZE + 1, aid_qf_errmsg); | 266 errmsglen = CMDBUFFSIZE + 1; |
267 errmsg = alloc_id(errmsglen, aid_qf_errmsg); | |
254 pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern); | 268 pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern); |
255 if (namebuf == NULL || errmsg == NULL || pattern == NULL) | 269 if (namebuf == NULL || errmsg == NULL || pattern == NULL) |
256 goto qf_init_end; | 270 goto qf_init_end; |
257 | 271 |
258 if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL) | 272 if (efile != NULL && (fd = mch_fopen((char *)efile, "r")) == NULL) |
511 if (tv->v_type == VAR_STRING) | 525 if (tv->v_type == VAR_STRING) |
512 { | 526 { |
513 /* Get the next line from the supplied string */ | 527 /* Get the next line from the supplied string */ |
514 char_u *p; | 528 char_u *p; |
515 | 529 |
516 if (!*p_str) /* Reached the end of the string */ | 530 if (*p_str == NUL) /* Reached the end of the string */ |
517 break; | 531 break; |
518 | 532 |
519 p = vim_strchr(p_str, '\n'); | 533 p = vim_strchr(p_str, '\n'); |
520 if (p) | 534 if (p != NULL) |
521 len = (int)(p - p_str + 1); | 535 len = (int)(p - p_str) + 1; |
522 else | 536 else |
523 len = (int)STRLEN(p_str); | 537 len = (int)STRLEN(p_str); |
524 | 538 |
525 if (len > CMDBUFFSIZE - 2) | 539 if (len > IOSIZE - 2) |
526 vim_strncpy(IObuff, p_str, CMDBUFFSIZE - 2); | 540 { |
541 /* | |
542 * If the line exceeds LINE_MAXLEN exclude the last | |
543 * byte since it's not a NL character. | |
544 */ | |
545 linelen = len > LINE_MAXLEN ? LINE_MAXLEN - 1 : len; | |
546 if (growbuf == NULL) | |
547 { | |
548 growbuf = alloc(linelen); | |
549 growbufsiz = linelen; | |
550 } | |
551 else if (linelen > growbufsiz) | |
552 { | |
553 growbuf = vim_realloc(growbuf, linelen); | |
554 if (growbuf == NULL) | |
555 goto qf_init_end; | |
556 growbufsiz = linelen; | |
557 } | |
558 linebuf = growbuf; | |
559 } | |
527 else | 560 else |
528 vim_strncpy(IObuff, p_str, len); | 561 { |
529 | 562 linebuf = IObuff; |
563 linelen = len; | |
564 } | |
565 vim_strncpy(linebuf, p_str, linelen); | |
566 | |
567 /* | |
568 * Increment using len in order to discard the rest of the | |
569 * line if it exceeds LINE_MAXLEN. | |
570 */ | |
530 p_str += len; | 571 p_str += len; |
531 } | 572 } |
532 else if (tv->v_type == VAR_LIST) | 573 else if (tv->v_type == VAR_LIST) |
533 { | 574 { |
534 /* Get the next line from the supplied list */ | 575 /* Get the next line from the supplied list */ |
535 while (p_li && (p_li->li_tv.v_type != VAR_STRING | 576 while (p_li != NULL |
536 || p_li->li_tv.vval.v_string == NULL)) | 577 && (p_li->li_tv.v_type != VAR_STRING |
578 || p_li->li_tv.vval.v_string == NULL)) | |
537 p_li = p_li->li_next; /* Skip non-string items */ | 579 p_li = p_li->li_next; /* Skip non-string items */ |
538 | 580 |
539 if (!p_li) /* End of the list */ | 581 if (p_li == NULL) /* End of the list */ |
540 break; | 582 break; |
541 | 583 |
542 len = (int)STRLEN(p_li->li_tv.vval.v_string); | 584 len = (int)STRLEN(p_li->li_tv.vval.v_string); |
543 if (len > CMDBUFFSIZE - 2) | 585 if (len > IOSIZE - 2) |
544 len = CMDBUFFSIZE - 2; | 586 { |
545 | 587 linelen = len; |
546 vim_strncpy(IObuff, p_li->li_tv.vval.v_string, len); | 588 if (linelen > LINE_MAXLEN) |
589 linelen = LINE_MAXLEN - 1; | |
590 if (growbuf == NULL) | |
591 { | |
592 growbuf = alloc(linelen); | |
593 growbufsiz = linelen; | |
594 } | |
595 else if (linelen > growbufsiz) | |
596 { | |
597 if ((growbuf = vim_realloc(growbuf, | |
598 linelen)) == NULL) | |
599 goto qf_init_end; | |
600 growbufsiz = linelen; | |
601 } | |
602 linebuf = growbuf; | |
603 } | |
604 else | |
605 { | |
606 linebuf = IObuff; | |
607 linelen = len; | |
608 } | |
609 | |
610 vim_strncpy(linebuf, p_li->li_tv.vval.v_string, linelen); | |
547 | 611 |
548 p_li = p_li->li_next; /* next item */ | 612 p_li = p_li->li_next; /* next item */ |
549 } | 613 } |
550 } | 614 } |
551 else | 615 else |
552 { | 616 { |
553 /* Get the next line from the supplied buffer */ | 617 /* Get the next line from the supplied buffer */ |
554 if (buflnum > lnumlast) | 618 if (buflnum > lnumlast) |
555 break; | 619 break; |
556 vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE), | 620 p_buf = ml_get_buf(buf, buflnum++, FALSE); |
557 CMDBUFFSIZE - 2); | 621 linelen = (int)STRLEN(p_buf); |
622 if (linelen > IOSIZE - 2) | |
623 { | |
624 if (growbuf == NULL) | |
625 { | |
626 growbuf = alloc(linelen); | |
627 growbufsiz = linelen; | |
628 } | |
629 else if (linelen > growbufsiz) | |
630 { | |
631 if (linelen > LINE_MAXLEN) | |
632 linelen = LINE_MAXLEN - 1; | |
633 if ((growbuf = vim_realloc(growbuf, linelen)) == NULL) | |
634 goto qf_init_end; | |
635 growbufsiz = linelen; | |
636 } | |
637 linebuf = growbuf; | |
638 } | |
639 else | |
640 linebuf = IObuff; | |
641 vim_strncpy(linebuf, p_buf, linelen); | |
558 } | 642 } |
559 } | 643 } |
560 else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL) | 644 else |
561 break; | 645 { |
562 | 646 if (fgets((char *)IObuff, IOSIZE, fd) == NULL) |
563 IObuff[CMDBUFFSIZE - 2] = NUL; /* for very long lines */ | 647 break; |
648 | |
649 discard = FALSE; | |
650 linelen = (int)STRLEN(IObuff); | |
651 if (linelen == IOSIZE - 1 && (IObuff[linelen - 1] != '\n' | |
652 #ifdef USE_CRNL | |
653 || IObuff[linelen - 1] != '\r' | |
654 #endif | |
655 )) | |
656 { | |
657 /* | |
658 * The current line exceeds IObuff, continue reading using | |
659 * growbuf until EOL or LINE_MAXLEN bytes is read. | |
660 */ | |
661 if (growbuf == NULL) | |
662 { | |
663 growbufsiz = 2 * (IOSIZE - 1); | |
664 growbuf = alloc(growbufsiz); | |
665 if (growbuf == NULL) | |
666 goto qf_init_end; | |
667 } | |
668 | |
669 /* Copy the read part of the line, excluding null-terminator */ | |
670 memcpy(growbuf, IObuff, IOSIZE - 1); | |
671 growbuflen = linelen; | |
672 | |
673 for (;;) | |
674 { | |
675 if (fgets((char *)growbuf + growbuflen, | |
676 growbufsiz - growbuflen, fd) == NULL) | |
677 break; | |
678 linelen = STRLEN(growbuf + growbuflen); | |
679 growbuflen += linelen; | |
680 if (growbuf[growbuflen - 1] == '\n' | |
681 #ifdef USE_CRNL | |
682 || growbuf[growbuflen - 1] == '\r' | |
683 #endif | |
684 ) | |
685 break; | |
686 if (growbufsiz == LINE_MAXLEN) | |
687 { | |
688 discard = TRUE; | |
689 break; | |
690 } | |
691 | |
692 growbufsiz = 2 * growbufsiz < LINE_MAXLEN | |
693 ? 2 * growbufsiz : LINE_MAXLEN; | |
694 growbuf = vim_realloc(growbuf, 2 * growbufsiz); | |
695 if (growbuf == NULL) | |
696 goto qf_init_end; | |
697 } | |
698 | |
699 while (discard) | |
700 { | |
701 /* | |
702 * The current line is longer than LINE_MAXLEN, continue | |
703 * reading but discard everything until EOL or EOF is | |
704 * reached. | |
705 */ | |
706 if (fgets((char *)IObuff, IOSIZE, fd) == NULL | |
707 || (int)STRLEN(IObuff) < IOSIZE - 1 | |
708 || IObuff[IOSIZE - 1] == '\n' | |
709 #ifdef USE_CRNL | |
710 || IObuff[IOSIZE - 1] == '\r' | |
711 #endif | |
712 ) | |
713 break; | |
714 } | |
715 | |
716 linebuf = growbuf; | |
717 linelen = growbuflen; | |
718 } | |
719 else | |
720 linebuf = IObuff; | |
721 } | |
722 | |
723 if (linelen > 0 && linebuf[linelen - 1] == '\n') | |
724 linebuf[linelen - 1] = NUL; | |
725 #ifdef USE_CRNL | |
726 if (linelen > 0 && linebuf[linelen - 1] == '\r') | |
727 linebuf[linelen - 1] = NUL; | |
728 #endif | |
729 | |
564 #ifdef FEAT_MBYTE | 730 #ifdef FEAT_MBYTE |
565 remove_bom(IObuff); | 731 remove_bom(linebuf); |
566 #endif | |
567 | |
568 if ((efmp = vim_strrchr(IObuff, '\n')) != NULL) | |
569 *efmp = NUL; | |
570 #ifdef USE_CRNL | |
571 if ((efmp = vim_strrchr(IObuff, '\r')) != NULL) | |
572 *efmp = NUL; | |
573 #endif | 732 #endif |
574 | 733 |
575 /* If there was no %> item start at the first pattern */ | 734 /* If there was no %> item start at the first pattern */ |
576 if (fmt_start == NULL) | 735 if (fmt_start == NULL) |
577 fmt_ptr = fmt_first; | 736 fmt_ptr = fmt_first; |
604 enr = -1; | 763 enr = -1; |
605 type = 0; | 764 type = 0; |
606 tail = NULL; | 765 tail = NULL; |
607 | 766 |
608 regmatch.regprog = fmt_ptr->prog; | 767 regmatch.regprog = fmt_ptr->prog; |
609 r = vim_regexec(®match, IObuff, (colnr_T)0); | 768 r = vim_regexec(®match, linebuf, (colnr_T)0); |
610 fmt_ptr->prog = regmatch.regprog; | 769 fmt_ptr->prog = regmatch.regprog; |
611 if (r) | 770 if (r) |
612 { | 771 { |
613 if ((idx == 'C' || idx == 'Z') && !multiline) | 772 if ((idx == 'C' || idx == 'Z') && !multiline) |
614 continue; | 773 continue; |
661 if (regmatch.startp[i] == NULL) | 820 if (regmatch.startp[i] == NULL) |
662 continue; | 821 continue; |
663 type = *regmatch.startp[i]; | 822 type = *regmatch.startp[i]; |
664 } | 823 } |
665 if (fmt_ptr->flags == '+' && !multiscan) /* %+ */ | 824 if (fmt_ptr->flags == '+' && !multiscan) /* %+ */ |
666 STRCPY(errmsg, IObuff); | 825 { |
826 if (linelen > errmsglen) { | |
827 /* linelen + null terminator */ | |
828 if ((errmsg = vim_realloc(errmsg, linelen + 1)) == NULL) | |
829 goto qf_init_end; | |
830 errmsglen = linelen + 1; | |
831 } | |
832 vim_strncpy(errmsg, linebuf, linelen); | |
833 } | |
667 else if ((i = (int)fmt_ptr->addr[5]) > 0) /* %m */ | 834 else if ((i = (int)fmt_ptr->addr[5]) > 0) /* %m */ |
668 { | 835 { |
669 if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) | 836 if (regmatch.startp[i] == NULL || regmatch.endp[i] == NULL) |
670 continue; | 837 continue; |
671 len = (int)(regmatch.endp[i] - regmatch.startp[i]); | 838 len = (int)(regmatch.endp[i] - regmatch.startp[i]); |
839 if (len > errmsglen) { | |
840 /* len + null terminator */ | |
841 if ((errmsg = vim_realloc(errmsg, len + 1)) | |
842 == NULL) | |
843 goto qf_init_end; | |
844 errmsglen = len + 1; | |
845 } | |
672 vim_strncpy(errmsg, regmatch.startp[i], len); | 846 vim_strncpy(errmsg, regmatch.startp[i], len); |
673 } | 847 } |
674 if ((i = (int)fmt_ptr->addr[6]) > 0) /* %r */ | 848 if ((i = (int)fmt_ptr->addr[6]) > 0) /* %r */ |
675 { | 849 { |
676 if (regmatch.startp[i] == NULL) | 850 if (regmatch.startp[i] == NULL) |
740 directory = qf_pop_dir(&dir_stack); | 914 directory = qf_pop_dir(&dir_stack); |
741 } | 915 } |
742 namebuf[0] = NUL; /* no match found, remove file name */ | 916 namebuf[0] = NUL; /* no match found, remove file name */ |
743 lnum = 0; /* don't jump to this line */ | 917 lnum = 0; /* don't jump to this line */ |
744 valid = FALSE; | 918 valid = FALSE; |
745 STRCPY(errmsg, IObuff); /* copy whole line to error message */ | 919 if (linelen > errmsglen) { |
920 /* linelen + null terminator */ | |
921 if ((errmsg = vim_realloc(errmsg, linelen + 1)) == NULL) | |
922 goto qf_init_end; | |
923 errmsglen = linelen + 1; | |
924 } | |
925 /* copy whole line to error message */ | |
926 vim_strncpy(errmsg, linebuf, linelen); | |
746 if (fmt_ptr == NULL) | 927 if (fmt_ptr == NULL) |
747 multiline = multiignore = FALSE; | 928 multiline = multiignore = FALSE; |
748 } | 929 } |
749 else if (fmt_ptr != NULL) | 930 else if (fmt_ptr != NULL) |
750 { | 931 { |
876 qf_init_end: | 1057 qf_init_end: |
877 vim_free(namebuf); | 1058 vim_free(namebuf); |
878 vim_free(errmsg); | 1059 vim_free(errmsg); |
879 vim_free(pattern); | 1060 vim_free(pattern); |
880 vim_free(fmtstr); | 1061 vim_free(fmtstr); |
1062 vim_free(growbuf); | |
881 | 1063 |
882 #ifdef FEAT_WINDOWS | 1064 #ifdef FEAT_WINDOWS |
883 qf_update_buffer(qi, TRUE); | 1065 qf_update_buffer(qi, TRUE); |
884 #endif | 1066 #endif |
885 | 1067 |