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(&regmatch, IObuff, (colnr_T)0); 768 r = vim_regexec(&regmatch, 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