To: vim_dev@googlegroups.com Subject: Patch 7.4.1881 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1881 Problem: Appending to a long quickfix list is slow. Solution: Add qf_last. Files: src/quickfix.c *** ../vim-7.4.1880/src/quickfix.c 2016-06-02 13:40:00.820702274 +0200 --- src/quickfix.c 2016-06-02 22:07:47.024283187 +0200 *************** *** 52,57 **** --- 52,58 ---- typedef struct qf_list_S { qfline_T *qf_start; /* pointer to the first error */ + qfline_T *qf_last; /* pointer to the last error */ qfline_T *qf_ptr; /* pointer to the current error */ int qf_count; /* number of errors (0 means no error list) */ int qf_index; /* current index in the error list */ *************** *** 110,116 **** static void qf_store_title(qf_info_T *qi, char_u *title); static void qf_new_list(qf_info_T *qi, char_u *qf_title); static void ll_free_all(qf_info_T **pqi); ! static int qf_add_entry(qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); static qf_info_T *ll_new_list(void); static void qf_msg(qf_info_T *qi); static void qf_free(qf_info_T *qi, int idx); --- 111,117 ---- static void qf_store_title(qf_info_T *qi, char_u *title); static void qf_new_list(qf_info_T *qi, char_u *qf_title); static void ll_free_all(qf_info_T **pqi); ! static int qf_add_entry(qf_info_T *qi, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); static qf_info_T *ll_new_list(void); static void qf_msg(qf_info_T *qi); static void qf_free(qf_info_T *qi, int idx); *************** *** 245,251 **** long lnum = 0L; int enr = 0; FILE *fd = NULL; - qfline_T *qfprev = NULL; /* init to make SASC shut up */ #ifdef FEAT_WINDOWS qfline_T *old_last = NULL; #endif --- 246,251 ---- *************** *** 307,320 **** if (newlist || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, qf_title); else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) { ! /* Adding to existing list, find last entry. */ ! for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start; ! qfprev->qf_next != qfprev; qfprev = qfprev->qf_next) ! ; ! old_last = qfprev; } /* * Each part of the format string is copied and modified from errorformat to --- 307,319 ---- if (newlist || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, qf_title); + #ifdef FEAT_WINDOWS else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) { ! /* Adding to existing list, use last entry. */ ! old_last = qi->qf_lists[qi->qf_curlist].qf_last; } + #endif /* * Each part of the format string is copied and modified from errorformat to *************** *** 936,941 **** --- 935,942 ---- } else if (vim_strchr((char_u *)"CZ", idx) != NULL) { /* continuation of multi-line msg */ + qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last; + if (qfprev == NULL) goto error2; if (*errmsg && !multiignore) *************** *** 995,1001 **** } } ! if (qf_add_entry(qi, &qfprev, directory, (*namebuf || directory) ? namebuf --- 996,1002 ---- } } ! if (qf_add_entry(qi, directory, (*namebuf || directory) ? namebuf *************** *** 1159,1165 **** static int qf_add_entry( qf_info_T *qi, /* quickfix list */ - qfline_T **prevp, /* pointer to previously added entry or NULL */ char_u *dir, /* optional directory name */ char_u *fname, /* file name or NULL */ int bufnum, /* buffer number or zero */ --- 1160,1165 ---- *************** *** 1173,1178 **** --- 1173,1179 ---- int valid) /* valid entry */ { qfline_T *qfp; + qfline_T **lastp; /* pointer to qf_last or NULL */ if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL) return FAIL; *************** *** 1202,1223 **** qfp->qf_type = type; qfp->qf_valid = valid; if (qi->qf_lists[qi->qf_curlist].qf_count == 0) /* first element in the list */ { qi->qf_lists[qi->qf_curlist].qf_start = qfp; qi->qf_lists[qi->qf_curlist].qf_ptr = qfp; qi->qf_lists[qi->qf_curlist].qf_index = 0; ! qfp->qf_prev = qfp; /* first element points to itself */ } else { ! qfp->qf_prev = *prevp; ! (*prevp)->qf_next = qfp; } ! qfp->qf_next = qfp; /* last element points to itself */ qfp->qf_cleared = FALSE; ! *prevp = qfp; ++qi->qf_lists[qi->qf_curlist].qf_count; if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid) /* first valid entry */ --- 1203,1225 ---- qfp->qf_type = type; qfp->qf_valid = valid; + lastp = &qi->qf_lists[qi->qf_curlist].qf_last; if (qi->qf_lists[qi->qf_curlist].qf_count == 0) /* first element in the list */ { qi->qf_lists[qi->qf_curlist].qf_start = qfp; qi->qf_lists[qi->qf_curlist].qf_ptr = qfp; qi->qf_lists[qi->qf_curlist].qf_index = 0; ! qfp->qf_prev = NULL; } else { ! qfp->qf_prev = *lastp; ! (*lastp)->qf_next = qfp; } ! qfp->qf_next = NULL; qfp->qf_cleared = FALSE; ! *lastp = qfp; ++qi->qf_lists[qi->qf_curlist].qf_count; if (qi->qf_lists[qi->qf_curlist].qf_index == 0 && qfp->qf_valid) /* first valid entry */ *************** *** 1315,1320 **** --- 1317,1323 ---- to_qfl->qf_count = 0; to_qfl->qf_index = 0; to_qfl->qf_start = NULL; + to_qfl->qf_last = NULL; to_qfl->qf_ptr = NULL; if (from_qfl->qf_title != NULL) to_qfl->qf_title = vim_strsave(from_qfl->qf_title); *************** *** 1324,1336 **** if (from_qfl->qf_count) { qfline_T *from_qfp; ! qfline_T *prevp = NULL; /* copy all the location entries in this list */ ! for (i = 0, from_qfp = from_qfl->qf_start; i < from_qfl->qf_count; ! ++i, from_qfp = from_qfp->qf_next) { ! if (qf_add_entry(to->w_llist, &prevp, NULL, NULL, 0, --- 1327,1340 ---- if (from_qfl->qf_count) { qfline_T *from_qfp; ! qfline_T *prevp; /* copy all the location entries in this list */ ! for (i = 0, from_qfp = from_qfl->qf_start; ! i < from_qfl->qf_count && from_qfp != NULL; ! ++i, from_qfp = from_qfp->qf_next) { ! if (qf_add_entry(to->w_llist, NULL, NULL, 0, *************** *** 1351,1356 **** --- 1355,1361 ---- * directory and file names are not supplied. So the qf_fnum * field is copied here. */ + prevp = to->w_llist->qf_lists[to->w_llist->qf_curlist].qf_last; prevp->qf_fnum = from_qfp->qf_fnum; /* file number */ prevp->qf_type = from_qfp->qf_type; /* error type */ if (from_qfl->qf_ptr == from_qfp) *************** *** 1611,1617 **** /* Search for the entry in the current list */ for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; ++i, qfp = qfp->qf_next) ! if (qfp == qf_ptr) break; if (i == qfl->qf_count) /* Entry is not found */ --- 1616,1622 ---- /* Search for the entry in the current list */ for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; ++i, qfp = qfp->qf_next) ! if (qfp == NULL || qfp == qf_ptr) break; if (i == qfl->qf_count) /* Entry is not found */ *************** *** 2267,2272 **** --- 2272,2279 ---- } qfp = qfp->qf_next; + if (qfp == NULL) + break; ++i; ui_breakcheck(); } *************** *** 2365,2388 **** qf_free(qf_info_T *qi, int idx) { qfline_T *qfp; int stop = FALSE; ! while (qi->qf_lists[idx].qf_count) { ! qfp = qi->qf_lists[idx].qf_start->qf_next; if (qi->qf_lists[idx].qf_title != NULL && !stop) { ! vim_free(qi->qf_lists[idx].qf_start->qf_text); ! stop = (qi->qf_lists[idx].qf_start == qfp); ! vim_free(qi->qf_lists[idx].qf_start->qf_pattern); ! vim_free(qi->qf_lists[idx].qf_start); if (stop) /* Somehow qf_count may have an incorrect value, set it to 1 * to avoid crashing when it's wrong. * TODO: Avoid qf_count being incorrect. */ qi->qf_lists[idx].qf_count = 1; } ! qi->qf_lists[idx].qf_start = qfp; --qi->qf_lists[idx].qf_count; } vim_free(qi->qf_lists[idx].qf_title); --- 2372,2397 ---- qf_free(qf_info_T *qi, int idx) { qfline_T *qfp; + qfline_T *qfpnext; int stop = FALSE; ! while (qi->qf_lists[idx].qf_count && qi->qf_lists[idx].qf_start != NULL) { ! qfp = qi->qf_lists[idx].qf_start; ! qfpnext = qfp->qf_next; if (qi->qf_lists[idx].qf_title != NULL && !stop) { ! vim_free(qfp->qf_text); ! stop = (qfp == qfpnext); ! vim_free(qfp->qf_pattern); ! vim_free(qfp); if (stop) /* Somehow qf_count may have an incorrect value, set it to 1 * to avoid crashing when it's wrong. * TODO: Avoid qf_count being incorrect. */ qi->qf_lists[idx].qf_count = 1; } ! qi->qf_lists[idx].qf_start = qfpnext; --qi->qf_lists[idx].qf_count; } vim_free(qi->qf_lists[idx].qf_title); *************** *** 2416,2422 **** for (idx = 0; idx < qi->qf_listcount; ++idx) if (qi->qf_lists[idx].qf_count) for (i = 0, qfp = qi->qf_lists[idx].qf_start; ! i < qi->qf_lists[idx].qf_count; ++i, qfp = qfp->qf_next) if (qfp->qf_fnum == curbuf->b_fnum) { if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) --- 2425,2432 ---- for (idx = 0; idx < qi->qf_listcount; ++idx) if (qi->qf_lists[idx].qf_count) for (i = 0, qfp = qi->qf_lists[idx].qf_start; ! i < qi->qf_lists[idx].qf_count && qfp != NULL; ! ++i, qfp = qfp->qf_next) if (qfp->qf_fnum == curbuf->b_fnum) { if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) *************** *** 2930,2935 **** --- 2940,2947 ---- break; ++lnum; qfp = qfp->qf_next; + if (qfp == NULL) + break; } if (old_last == NULL) *************** *** 3226,3232 **** } for (i = 0, qfp = qi->qf_lists[qi->qf_curlist].qf_start; ! (i < qi->qf_lists[qi->qf_curlist].qf_count) && (qfp != NULL); ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) --- 3238,3244 ---- } for (i = 0, qfp = qi->qf_lists[qi->qf_curlist].qf_start; ! i < qi->qf_lists[qi->qf_curlist].qf_count && qfp != NULL; ++i, qfp = qfp->qf_next) { if (qfp->qf_valid) *************** *** 3332,3338 **** if (qfl->qf_count <= 0 || qfl->qf_nonevalid) return 1; ! for (i = 1, eidx = 0; i <= qfl->qf_count && qfp!= NULL; i++, qfp = qfp->qf_next) { if (qfp->qf_valid) --- 3344,3350 ---- if (qfl->qf_count <= 0 || qfl->qf_nonevalid) return 1; ! for (i = 1, eidx = 0; i <= qfl->qf_count && qfp != NULL; i++, qfp = qfp->qf_next) { if (qfp->qf_valid) *************** *** 3560,3566 **** #ifdef FEAT_AUTOCMD qfline_T *cur_qf_start; #endif - qfline_T *prevp = NULL; long lnum; buf_T *buf; int duplicate_name = FALSE; --- 3572,3577 ---- *************** *** 3659,3669 **** || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title != NULL ? title : *eap->cmdlinep); - else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) - /* Adding to existing list, find last entry. */ - for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; - prevp->qf_next != prevp; prevp = prevp->qf_next) - ; /* parse the list of arguments */ if (get_arglist_exp(p, &fcount, &fnames, TRUE) == FAIL) --- 3670,3675 ---- *************** *** 3787,3793 **** col, NULL) > 0) { ; ! if (qf_add_entry(qi, &prevp, NULL, /* dir */ fname, 0, --- 3793,3799 ---- col, NULL) > 0) { ; ! if (qf_add_entry(qi, NULL, /* dir */ fname, 0, *************** *** 4213,4218 **** --- 4219,4226 ---- return FAIL; qfp = qfp->qf_next; + if (qfp == NULL) + break; } return OK; } *************** *** 4236,4242 **** long lnum; int col, nr; int vcol; - qfline_T *prevp = NULL; #ifdef FEAT_WINDOWS qfline_T *old_last = NULL; #endif --- 4244,4249 ---- *************** *** 4255,4270 **** if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title); - else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0) - { - /* Adding to existing list, find last entry. */ - for (prevp = qi->qf_lists[qi->qf_curlist].qf_start; - prevp->qf_next != prevp; prevp = prevp->qf_next) - ; #ifdef FEAT_WINDOWS ! old_last = prevp; #endif - } else if (action == 'r') { qf_free(qi, qi->qf_curlist); --- 4262,4272 ---- if (action == ' ' || qi->qf_curlist == qi->qf_listcount) /* make place for a new list */ qf_new_list(qi, title); #ifdef FEAT_WINDOWS ! else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0) ! /* Adding to existing list, use last entry. */ ! old_last = qi->qf_lists[qi->qf_curlist].qf_last; #endif else if (action == 'r') { qf_free(qi, qi->qf_curlist); *************** *** 4309,4315 **** bufnum = 0; } ! status = qf_add_entry(qi, &prevp, NULL, /* dir */ filename, bufnum, --- 4311,4317 ---- bufnum = 0; } ! status = qf_add_entry(qi, NULL, /* dir */ filename, bufnum, *************** *** 4473,4479 **** char_u **fnames; FILE *fd; int fi; - qfline_T *prevp = NULL; long lnum; #ifdef FEAT_MULTI_LANG char_u *lang; --- 4475,4480 ---- *************** *** 4599,4605 **** while (l > 0 && line[l - 1] <= ' ') line[--l] = NUL; ! if (qf_add_entry(qi, &prevp, NULL, /* dir */ fnames[fi], 0, --- 4600,4606 ---- while (l > 0 && line[l - 1] <= ' ') line[--l] = NUL; ! if (qf_add_entry(qi, NULL, /* dir */ fnames[fi], 0, *** ../vim-7.4.1880/src/version.c 2016-06-02 20:26:37.296366681 +0200 --- src/version.c 2016-06-02 21:25:06.460318410 +0200 *************** *** 755,756 **** --- 755,758 ---- { /* Add new patch number below this line */ + /**/ + 1881, /**/ -- You have the right to remain silent. Anything you say will be misquoted, then used against you. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///