Mercurial > vim
comparison src/quickfix.c @ 13992:710b1bb82f2c v8.1.0014
patch 8.1.0014: qf_init_ext() is too long
commit https://github.com/vim/vim/commit/6053f2d29a979ffed1fe01b0a2f28e23750530e9
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon May 21 16:56:38 2018 +0200
patch 8.1.0014: qf_init_ext() is too long
Problem: qf_init_ext() is too long.
Solution: Split it into multiple functions. (Yegappan Lakshmanan,
closes #2939)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 21 May 2018 17:00:06 +0200 |
parents | 9b1dc5c2f460 |
children | 59e76d550c10 |
comparison
equal
deleted
inserted
replaced
13991:e34014a5bfd8 | 13992:710b1bb82f2c |
---|---|
132 int conthere; /* %> used */ | 132 int conthere; /* %> used */ |
133 }; | 133 }; |
134 | 134 |
135 static efm_T *fmt_start = NULL; /* cached across qf_parse_line() calls */ | 135 static efm_T *fmt_start = NULL; /* cached across qf_parse_line() calls */ |
136 | 136 |
137 static int qf_init_ext(qf_info_T *qi, int qf_idx, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc); | |
138 static void qf_new_list(qf_info_T *qi, char_u *qf_title); | 137 static void qf_new_list(qf_info_T *qi, char_u *qf_title); |
139 static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, char_u *module, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); | 138 static int qf_add_entry(qf_info_T *qi, int qf_idx, char_u *dir, char_u *fname, char_u *module, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid); |
140 static qf_info_T *ll_new_list(void); | |
141 static void qf_free(qf_info_T *qi, int idx); | 139 static void qf_free(qf_info_T *qi, int idx); |
142 static char_u *qf_types(int, int); | 140 static char_u *qf_types(int, int); |
143 static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *); | 141 static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *); |
144 static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); | 142 static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); |
145 static char_u *qf_pop_dir(struct dir_stack_T **); | 143 static char_u *qf_pop_dir(struct dir_stack_T **); |
174 static char_u *qf_last_bufname = NULL; | 172 static char_u *qf_last_bufname = NULL; |
175 static bufref_T qf_last_bufref = {NULL, 0, 0}; | 173 static bufref_T qf_last_bufref = {NULL, 0, 0}; |
176 | 174 |
177 static char *e_loc_list_changed = | 175 static char *e_loc_list_changed = |
178 N_("E926: Current location list was changed"); | 176 N_("E926: Current location list was changed"); |
179 | |
180 /* | |
181 * Read the errorfile "efile" into memory, line by line, building the error | |
182 * list. Set the error list's title to qf_title. | |
183 * Return -1 for error, number of errors for success. | |
184 */ | |
185 int | |
186 qf_init(win_T *wp, | |
187 char_u *efile, | |
188 char_u *errorformat, | |
189 int newlist, /* TRUE: start a new error list */ | |
190 char_u *qf_title, | |
191 char_u *enc) | |
192 { | |
193 qf_info_T *qi = &ql_info; | |
194 | |
195 if (wp != NULL) | |
196 { | |
197 qi = ll_get_or_alloc_list(wp); | |
198 if (qi == NULL) | |
199 return FAIL; | |
200 } | |
201 | |
202 return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, | |
203 newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); | |
204 } | |
205 | 177 |
206 /* | 178 /* |
207 * Maximum number of bytes allowed per line while reading a errorfile. | 179 * Maximum number of bytes allowed per line while reading a errorfile. |
208 */ | 180 */ |
209 #define LINE_MAXLEN 4096 | 181 #define LINE_MAXLEN 4096 |
1334 | 1306 |
1335 return QF_OK; | 1307 return QF_OK; |
1336 } | 1308 } |
1337 | 1309 |
1338 /* | 1310 /* |
1311 * Allocate the fields used for parsing lines and populating a quickfix list. | |
1312 */ | |
1313 static int | |
1314 qf_alloc_fields(qffields_T *pfields) | |
1315 { | |
1316 pfields->namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf); | |
1317 pfields->module = alloc_id(CMDBUFFSIZE + 1, aid_qf_module); | |
1318 pfields->errmsglen = CMDBUFFSIZE + 1; | |
1319 pfields->errmsg = alloc_id(pfields->errmsglen, aid_qf_errmsg); | |
1320 pfields->pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern); | |
1321 if (pfields->namebuf == NULL || pfields->errmsg == NULL | |
1322 || pfields->pattern == NULL || pfields->module == NULL) | |
1323 return FAIL; | |
1324 | |
1325 return OK; | |
1326 } | |
1327 | |
1328 /* | |
1329 * Free the fields used for parsing lines and populating a quickfix list. | |
1330 */ | |
1331 static void | |
1332 qf_free_fields(qffields_T *pfields) | |
1333 { | |
1334 vim_free(pfields->namebuf); | |
1335 vim_free(pfields->module); | |
1336 vim_free(pfields->errmsg); | |
1337 vim_free(pfields->pattern); | |
1338 } | |
1339 | |
1340 /* | |
1341 * Setup the state information used for parsing lines and populating a | |
1342 * quickfix list. | |
1343 */ | |
1344 static int | |
1345 qf_setup_state( | |
1346 qfstate_T *pstate, | |
1347 char_u *enc, | |
1348 char_u *efile, | |
1349 typval_T *tv, | |
1350 buf_T *buf, | |
1351 linenr_T lnumfirst, | |
1352 linenr_T lnumlast) | |
1353 { | |
1354 #ifdef FEAT_MBYTE | |
1355 pstate->vc.vc_type = CONV_NONE; | |
1356 if (enc != NULL && *enc != NUL) | |
1357 convert_setup(&pstate->vc, enc, p_enc); | |
1358 #endif | |
1359 | |
1360 if (efile != NULL && (pstate->fd = mch_fopen((char *)efile, "r")) == NULL) | |
1361 { | |
1362 EMSG2(_(e_openerrf), efile); | |
1363 return FAIL; | |
1364 } | |
1365 | |
1366 if (tv != NULL) | |
1367 { | |
1368 if (tv->v_type == VAR_STRING) | |
1369 pstate->p_str = tv->vval.v_string; | |
1370 else if (tv->v_type == VAR_LIST) | |
1371 pstate->p_li = tv->vval.v_list->lv_first; | |
1372 pstate->tv = tv; | |
1373 } | |
1374 pstate->buf = buf; | |
1375 pstate->buflnum = lnumfirst; | |
1376 pstate->lnumlast = lnumlast; | |
1377 | |
1378 return OK; | |
1379 } | |
1380 | |
1381 /* | |
1382 * Cleanup the state information used for parsing lines and populating a | |
1383 * quickfix list. | |
1384 */ | |
1385 static void | |
1386 qf_cleanup_state(qfstate_T *pstate) | |
1387 { | |
1388 if (pstate->fd != NULL) | |
1389 fclose(pstate->fd); | |
1390 | |
1391 vim_free(pstate->growbuf); | |
1392 #ifdef FEAT_MBYTE | |
1393 if (pstate->vc.vc_type != CONV_NONE) | |
1394 convert_setup(&pstate->vc, NULL, NULL); | |
1395 #endif | |
1396 } | |
1397 | |
1398 /* | |
1339 * Read the errorfile "efile" into memory, line by line, building the error | 1399 * Read the errorfile "efile" into memory, line by line, building the error |
1340 * list. | 1400 * list. |
1341 * Alternative: when "efile" is NULL read errors from buffer "buf". | 1401 * Alternative: when "efile" is NULL read errors from buffer "buf". |
1342 * Alternative: when "tv" is not NULL get errors from the string or list. | 1402 * Alternative: when "tv" is not NULL get errors from the string or list. |
1343 * Always use 'errorformat' from "buf" if there is a local value. | 1403 * Always use 'errorformat' from "buf" if there is a local value. |
1373 /* Do not used the cached buffer, it may have been wiped out. */ | 1433 /* Do not used the cached buffer, it may have been wiped out. */ |
1374 VIM_CLEAR(qf_last_bufname); | 1434 VIM_CLEAR(qf_last_bufname); |
1375 | 1435 |
1376 vim_memset(&state, 0, sizeof(state)); | 1436 vim_memset(&state, 0, sizeof(state)); |
1377 vim_memset(&fields, 0, sizeof(fields)); | 1437 vim_memset(&fields, 0, sizeof(fields)); |
1378 #ifdef FEAT_MBYTE | 1438 if ((qf_alloc_fields(&fields) == FAIL) || |
1379 state.vc.vc_type = CONV_NONE; | 1439 (qf_setup_state(&state, enc, efile, tv, buf, |
1380 if (enc != NULL && *enc != NUL) | 1440 lnumfirst, lnumlast) == FAIL)) |
1381 convert_setup(&state.vc, enc, p_enc); | |
1382 #endif | |
1383 fields.namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf); | |
1384 fields.module = alloc_id(CMDBUFFSIZE + 1, aid_qf_module); | |
1385 fields.errmsglen = CMDBUFFSIZE + 1; | |
1386 fields.errmsg = alloc_id(fields.errmsglen, aid_qf_errmsg); | |
1387 fields.pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern); | |
1388 if (fields.namebuf == NULL || fields.errmsg == NULL | |
1389 || fields.pattern == NULL || fields.module == NULL) | |
1390 goto qf_init_end; | 1441 goto qf_init_end; |
1391 | |
1392 if (efile != NULL && (state.fd = mch_fopen((char *)efile, "r")) == NULL) | |
1393 { | |
1394 EMSG2(_(e_openerrf), efile); | |
1395 goto qf_init_end; | |
1396 } | |
1397 | 1442 |
1398 if (newlist || qf_idx == qi->qf_listcount) | 1443 if (newlist || qf_idx == qi->qf_listcount) |
1399 { | 1444 { |
1400 /* make place for a new list */ | 1445 /* make place for a new list */ |
1401 qf_new_list(qi, qf_title); | 1446 qf_new_list(qi, qf_title); |
1439 /* | 1484 /* |
1440 * got_int is reset here, because it was probably set when killing the | 1485 * got_int is reset here, because it was probably set when killing the |
1441 * ":make" command, but we still want to read the errorfile then. | 1486 * ":make" command, but we still want to read the errorfile then. |
1442 */ | 1487 */ |
1443 got_int = FALSE; | 1488 got_int = FALSE; |
1444 | |
1445 if (tv != NULL) | |
1446 { | |
1447 if (tv->v_type == VAR_STRING) | |
1448 state.p_str = tv->vval.v_string; | |
1449 else if (tv->v_type == VAR_LIST) | |
1450 state.p_li = tv->vval.v_list->lv_first; | |
1451 state.tv = tv; | |
1452 } | |
1453 state.buf = buf; | |
1454 state.buflnum = lnumfirst; | |
1455 state.lnumlast = lnumlast; | |
1456 | 1489 |
1457 /* | 1490 /* |
1458 * Read the lines in the error file one by one. | 1491 * Read the lines in the error file one by one. |
1459 * Try to recognize one of the error formats in each line. | 1492 * Try to recognize one of the error formats in each line. |
1460 */ | 1493 */ |
1524 qi->qf_listcount--; | 1557 qi->qf_listcount--; |
1525 if (qi->qf_curlist > 0) | 1558 if (qi->qf_curlist > 0) |
1526 --qi->qf_curlist; | 1559 --qi->qf_curlist; |
1527 } | 1560 } |
1528 qf_init_end: | 1561 qf_init_end: |
1529 if (state.fd != NULL) | |
1530 fclose(state.fd); | |
1531 vim_free(fields.namebuf); | |
1532 vim_free(fields.module); | |
1533 vim_free(fields.errmsg); | |
1534 vim_free(fields.pattern); | |
1535 vim_free(state.growbuf); | |
1536 | |
1537 if (qf_idx == qi->qf_curlist) | 1562 if (qf_idx == qi->qf_curlist) |
1538 qf_update_buffer(qi, old_last); | 1563 qf_update_buffer(qi, old_last); |
1539 #ifdef FEAT_MBYTE | 1564 qf_cleanup_state(&state); |
1540 if (state.vc.vc_type != CONV_NONE) | 1565 qf_free_fields(&fields); |
1541 convert_setup(&state.vc, NULL, NULL); | |
1542 #endif | |
1543 | 1566 |
1544 return retval; | 1567 return retval; |
1568 } | |
1569 | |
1570 /* | |
1571 * Read the errorfile "efile" into memory, line by line, building the error | |
1572 * list. Set the error list's title to qf_title. | |
1573 * Return -1 for error, number of errors for success. | |
1574 */ | |
1575 int | |
1576 qf_init(win_T *wp, | |
1577 char_u *efile, | |
1578 char_u *errorformat, | |
1579 int newlist, /* TRUE: start a new error list */ | |
1580 char_u *qf_title, | |
1581 char_u *enc) | |
1582 { | |
1583 qf_info_T *qi = &ql_info; | |
1584 | |
1585 if (wp != NULL) | |
1586 { | |
1587 qi = ll_get_or_alloc_list(wp); | |
1588 if (qi == NULL) | |
1589 return FAIL; | |
1590 } | |
1591 | |
1592 return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, | |
1593 newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); | |
1545 } | 1594 } |
1546 | 1595 |
1547 /* | 1596 /* |
1548 * Set the title of the specified quickfix list. Frees the previous title. | 1597 * Set the title of the specified quickfix list. Frees the previous title. |
1549 * Prepends ':' to the title. | 1598 * Prepends ':' to the title. |
3833 set_internal_string_var((char_u *)"w:quickfix_title", | 3882 set_internal_string_var((char_u *)"w:quickfix_title", |
3834 qi->qf_lists[qi->qf_curlist].qf_title); | 3883 qi->qf_lists[qi->qf_curlist].qf_title); |
3835 } | 3884 } |
3836 | 3885 |
3837 /* | 3886 /* |
3887 * Add an error line to the quickfix buffer. | |
3888 */ | |
3889 static int | |
3890 qf_buf_add_line(buf_T *buf, linenr_T lnum, qfline_T *qfp, char_u *dirname) | |
3891 { | |
3892 int len; | |
3893 buf_T *errbuf; | |
3894 | |
3895 if (qfp->qf_module != NULL) | |
3896 { | |
3897 STRCPY(IObuff, qfp->qf_module); | |
3898 len = (int)STRLEN(IObuff); | |
3899 } | |
3900 else if (qfp->qf_fnum != 0 | |
3901 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL | |
3902 && errbuf->b_fname != NULL) | |
3903 { | |
3904 if (qfp->qf_type == 1) /* :helpgrep */ | |
3905 STRCPY(IObuff, gettail(errbuf->b_fname)); | |
3906 else | |
3907 { | |
3908 /* shorten the file name if not done already */ | |
3909 if (errbuf->b_sfname == NULL | |
3910 || mch_isFullName(errbuf->b_sfname)) | |
3911 { | |
3912 if (*dirname == NUL) | |
3913 mch_dirname(dirname, MAXPATHL); | |
3914 shorten_buf_fname(errbuf, dirname, FALSE); | |
3915 } | |
3916 STRCPY(IObuff, errbuf->b_fname); | |
3917 } | |
3918 len = (int)STRLEN(IObuff); | |
3919 } | |
3920 else | |
3921 len = 0; | |
3922 IObuff[len++] = '|'; | |
3923 | |
3924 if (qfp->qf_lnum > 0) | |
3925 { | |
3926 sprintf((char *)IObuff + len, "%ld", qfp->qf_lnum); | |
3927 len += (int)STRLEN(IObuff + len); | |
3928 | |
3929 if (qfp->qf_col > 0) | |
3930 { | |
3931 sprintf((char *)IObuff + len, " col %d", qfp->qf_col); | |
3932 len += (int)STRLEN(IObuff + len); | |
3933 } | |
3934 | |
3935 sprintf((char *)IObuff + len, "%s", | |
3936 (char *)qf_types(qfp->qf_type, qfp->qf_nr)); | |
3937 len += (int)STRLEN(IObuff + len); | |
3938 } | |
3939 else if (qfp->qf_pattern != NULL) | |
3940 { | |
3941 qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); | |
3942 len += (int)STRLEN(IObuff + len); | |
3943 } | |
3944 IObuff[len++] = '|'; | |
3945 IObuff[len++] = ' '; | |
3946 | |
3947 /* Remove newlines and leading whitespace from the text. | |
3948 * For an unrecognized line keep the indent, the compiler may | |
3949 * mark a word with ^^^^. */ | |
3950 qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, | |
3951 IObuff + len, IOSIZE - len); | |
3952 | |
3953 if (ml_append_buf(buf, lnum, IObuff, | |
3954 (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) | |
3955 return FAIL; | |
3956 | |
3957 return OK; | |
3958 } | |
3959 | |
3960 /* | |
3838 * Fill current buffer with quickfix errors, replacing any previous contents. | 3961 * Fill current buffer with quickfix errors, replacing any previous contents. |
3839 * curbuf must be the quickfix buffer! | 3962 * curbuf must be the quickfix buffer! |
3840 * If "old_last" is not NULL append the items after this one. | 3963 * If "old_last" is not NULL append the items after this one. |
3841 * When "old_last" is NULL then "buf" must equal "curbuf"! Because | 3964 * When "old_last" is NULL then "buf" must equal "curbuf"! Because |
3842 * ml_delete() is used and autocommands will be triggered. | 3965 * ml_delete() is used and autocommands will be triggered. |
3844 static void | 3967 static void |
3845 qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) | 3968 qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) |
3846 { | 3969 { |
3847 linenr_T lnum; | 3970 linenr_T lnum; |
3848 qfline_T *qfp; | 3971 qfline_T *qfp; |
3849 buf_T *errbuf; | |
3850 int len; | |
3851 int old_KeyTyped = KeyTyped; | 3972 int old_KeyTyped = KeyTyped; |
3852 | 3973 |
3853 if (old_last == NULL) | 3974 if (old_last == NULL) |
3854 { | 3975 { |
3855 if (buf != curbuf) | 3976 if (buf != curbuf) |
3881 qfp = old_last->qf_next; | 4002 qfp = old_last->qf_next; |
3882 lnum = buf->b_ml.ml_line_count; | 4003 lnum = buf->b_ml.ml_line_count; |
3883 } | 4004 } |
3884 while (lnum < qi->qf_lists[qi->qf_curlist].qf_count) | 4005 while (lnum < qi->qf_lists[qi->qf_curlist].qf_count) |
3885 { | 4006 { |
3886 if (qfp->qf_module != NULL) | 4007 if (qf_buf_add_line(buf, lnum, qfp, dirname) == FAIL) |
3887 { | |
3888 STRCPY(IObuff, qfp->qf_module); | |
3889 len = (int)STRLEN(IObuff); | |
3890 } | |
3891 else if (qfp->qf_fnum != 0 | |
3892 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL | |
3893 && errbuf->b_fname != NULL) | |
3894 { | |
3895 if (qfp->qf_type == 1) /* :helpgrep */ | |
3896 STRCPY(IObuff, gettail(errbuf->b_fname)); | |
3897 else | |
3898 { | |
3899 /* shorten the file name if not done already */ | |
3900 if (errbuf->b_sfname == NULL | |
3901 || mch_isFullName(errbuf->b_sfname)) | |
3902 { | |
3903 if (*dirname == NUL) | |
3904 mch_dirname(dirname, MAXPATHL); | |
3905 shorten_buf_fname(errbuf, dirname, FALSE); | |
3906 } | |
3907 STRCPY(IObuff, errbuf->b_fname); | |
3908 } | |
3909 len = (int)STRLEN(IObuff); | |
3910 } | |
3911 else | |
3912 len = 0; | |
3913 IObuff[len++] = '|'; | |
3914 | |
3915 if (qfp->qf_lnum > 0) | |
3916 { | |
3917 sprintf((char *)IObuff + len, "%ld", qfp->qf_lnum); | |
3918 len += (int)STRLEN(IObuff + len); | |
3919 | |
3920 if (qfp->qf_col > 0) | |
3921 { | |
3922 sprintf((char *)IObuff + len, " col %d", qfp->qf_col); | |
3923 len += (int)STRLEN(IObuff + len); | |
3924 } | |
3925 | |
3926 sprintf((char *)IObuff + len, "%s", | |
3927 (char *)qf_types(qfp->qf_type, qfp->qf_nr)); | |
3928 len += (int)STRLEN(IObuff + len); | |
3929 } | |
3930 else if (qfp->qf_pattern != NULL) | |
3931 { | |
3932 qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); | |
3933 len += (int)STRLEN(IObuff + len); | |
3934 } | |
3935 IObuff[len++] = '|'; | |
3936 IObuff[len++] = ' '; | |
3937 | |
3938 /* Remove newlines and leading whitespace from the text. | |
3939 * For an unrecognized line keep the indent, the compiler may | |
3940 * mark a word with ^^^^. */ | |
3941 qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, | |
3942 IObuff + len, IOSIZE - len); | |
3943 | |
3944 if (ml_append_buf(buf, lnum, IObuff, | |
3945 (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) | |
3946 break; | 4008 break; |
4009 | |
3947 ++lnum; | 4010 ++lnum; |
3948 qfp = qfp->qf_next; | 4011 qfp = qfp->qf_next; |
3949 if (qfp == NULL) | 4012 if (qfp == NULL) |
3950 break; | 4013 break; |
3951 } | 4014 } |