1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * quickfix.c: functions for quickfix mode, using a file with error messages 12 */ 13 14 #include "vim.h" 15 16 #if defined(FEAT_QUICKFIX) || defined(PROTO) 17 18 struct dir_stack_T 19 { 20 struct dir_stack_T *next; 21 char_u *dirname; 22 }; 23 24 /* 25 * For each error the next struct is allocated and linked in a list. 26 */ 27 typedef struct qfline_S qfline_T; 28 struct qfline_S 29 { 30 qfline_T *qf_next; // pointer to next error in the list 31 qfline_T *qf_prev; // pointer to previous error in the list 32 linenr_T qf_lnum; // line number where the error occurred 33 int qf_fnum; // file number for the line 34 int qf_col; // column where the error occurred 35 int qf_nr; // error number 36 char_u *qf_module; // module name for this error 37 char_u *qf_pattern; // search pattern for the error 38 char_u *qf_text; // description of the error 39 char_u qf_viscol; // set to TRUE if qf_col is screen column 40 char_u qf_cleared; // set to TRUE if line has been deleted 41 char_u qf_type; // type of the error (mostly 'E'); 1 for 42 // :helpgrep 43 char_u qf_valid; // valid error message detected 44 }; 45 46 /* 47 * There is a stack of error lists. 48 */ 49 #define LISTCOUNT 10 50 #define INVALID_QFIDX (-1) 51 #define INVALID_QFBUFNR (0) 52 53 /* 54 * Quickfix list type. 55 */ 56 typedef enum 57 { 58 QFLT_QUICKFIX, // Quickfix list - global list 59 QFLT_LOCATION, // Location list - per window list 60 QFLT_INTERNAL // Internal - Temporary list used by getqflist()/getloclist() 61 } qfltype_T; 62 63 /* 64 * Quickfix/Location list definition 65 * Contains a list of entries (qfline_T). qf_start points to the first entry 66 * and qf_last points to the last entry. qf_count contains the list size. 67 * 68 * Usually the list contains one or more entries. But an empty list can be 69 * created using setqflist()/setloclist() with a title and/or user context 70 * information and entries can be added later using setqflist()/setloclist(). 71 */ 72 typedef struct qf_list_S 73 { 74 int_u qf_id; // Unique identifier for this list 75 qfltype_T qfl_type; 76 qfline_T *qf_start; // pointer to the first error 77 qfline_T *qf_last; // pointer to the last error 78 qfline_T *qf_ptr; // pointer to the current error 79 int qf_count; // number of errors (0 means empty list) 80 int qf_index; // current index in the error list 81 int qf_nonevalid; // TRUE if not a single valid entry found 82 char_u *qf_title; // title derived from the command that created 83 // the error list or set by setqflist 84 typval_T *qf_ctx; // context set by setqflist/setloclist 85 86 struct dir_stack_T *qf_dir_stack; 87 char_u *qf_directory; 88 struct dir_stack_T *qf_file_stack; 89 char_u *qf_currfile; 90 int qf_multiline; 91 int qf_multiignore; 92 int qf_multiscan; 93 long qf_changedtick; 94 } qf_list_T; 95 96 /* 97 * Quickfix/Location list stack definition 98 * Contains a list of quickfix/location lists (qf_list_T) 99 */ 100 struct qf_info_S 101 { 102 // Count of references to this list. Used only for location lists. 103 // When a location list window reference this list, qf_refcount 104 // will be 2. Otherwise, qf_refcount will be 1. When qf_refcount 105 // reaches 0, the list is freed. 106 int qf_refcount; 107 int qf_listcount; // current number of lists 108 int qf_curlist; // current error list 109 qf_list_T qf_lists[LISTCOUNT]; 110 qfltype_T qfl_type; // type of list 111 int qf_bufnr; // quickfix window buffer number 112 }; 113 114 static qf_info_T ql_info; // global quickfix list 115 static int_u last_qf_id = 0; // Last used quickfix list id 116 117 #define FMT_PATTERNS 11 // maximum number of % recognized 118 119 /* 120 * Structure used to hold the info of one part of 'errorformat' 121 */ 122 typedef struct efm_S efm_T; 123 struct efm_S 124 { 125 regprog_T *prog; // pre-formatted part of 'errorformat' 126 efm_T *next; // pointer to next (NULL if last) 127 char_u addr[FMT_PATTERNS]; // indices of used % patterns 128 char_u prefix; // prefix of this format line: 129 // 'D' enter directory 130 // 'X' leave directory 131 // 'A' start of multi-line message 132 // 'E' error message 133 // 'W' warning message 134 // 'I' informational message 135 // 'C' continuation line 136 // 'Z' end of multi-line message 137 // 'G' general, unspecific message 138 // 'P' push file (partial) message 139 // 'Q' pop/quit file (partial) message 140 // 'O' overread (partial) message 141 char_u flags; // additional flags given in prefix 142 // '-' do not include this line 143 // '+' include whole line in message 144 int conthere; // %> used 145 }; 146 147 // List of location lists to be deleted. 148 // Used to delay the deletion of locations lists by autocmds. 149 typedef struct qf_delq_S 150 { 151 struct qf_delq_S *next; 152 qf_info_T *qi; 153 } qf_delq_T; 154 static qf_delq_T *qf_delq_head = NULL; 155 156 // Counter to prevent autocmds from freeing up location lists when they are 157 // still being used. 158 static int quickfix_busy = 0; 159 160 static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls 161 162 static void qf_new_list(qf_info_T *qi, char_u *qf_title); 163 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); 164 static void qf_free(qf_list_T *qfl); 165 static char_u *qf_types(int, int); 166 static int qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *, char_u *); 167 static char_u *qf_push_dir(char_u *, struct dir_stack_T **, int is_file_stack); 168 static char_u *qf_pop_dir(struct dir_stack_T **); 169 static char_u *qf_guess_filepath(qf_list_T *qfl, char_u *); 170 static void qf_fmt_text(char_u *text, char_u *buf, int bufsize); 171 static int qf_win_pos_update(qf_info_T *qi, int old_qf_index); 172 static win_T *qf_find_win(qf_info_T *qi); 173 static buf_T *qf_find_buf(qf_info_T *qi); 174 static void qf_update_buffer(qf_info_T *qi, qfline_T *old_last); 175 static void qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last); 176 static buf_T *load_dummy_buffer(char_u *fname, char_u *dirname_start, char_u *resulting_dir); 177 static void wipe_dummy_buffer(buf_T *buf, char_u *dirname_start); 178 static void unload_dummy_buffer(buf_T *buf, char_u *dirname_start); 179 static qf_info_T *ll_get_or_alloc_list(win_T *); 180 181 // Quickfix window check helper macro 182 #define IS_QF_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref == NULL) 183 // Location list window check helper macro 184 #define IS_LL_WINDOW(wp) (bt_quickfix(wp->w_buffer) && wp->w_llist_ref != NULL) 185 186 // Quickfix and location list stack check helper macros 187 #define IS_QF_STACK(qi) (qi->qfl_type == QFLT_QUICKFIX) 188 #define IS_LL_STACK(qi) (qi->qfl_type == QFLT_LOCATION) 189 #define IS_QF_LIST(qfl) (qfl->qfl_type == QFLT_QUICKFIX) 190 #define IS_LL_LIST(qfl) (qfl->qfl_type == QFLT_LOCATION) 191 192 /* 193 * Return location list for window 'wp' 194 * For location list window, return the referenced location list 195 */ 196 #define GET_LOC_LIST(wp) (IS_LL_WINDOW(wp) ? wp->w_llist_ref : wp->w_llist) 197 198 /* 199 * Looking up a buffer can be slow if there are many. Remember the last one 200 * to make this a lot faster if there are multiple matches in the same file. 201 */ 202 static char_u *qf_last_bufname = NULL; 203 static bufref_T qf_last_bufref = {NULL, 0, 0}; 204 205 static char *e_loc_list_changed = 206 N_("E926: Current location list was changed"); 207 208 /* 209 * Maximum number of bytes allowed per line while reading a errorfile. 210 */ 211 #define LINE_MAXLEN 4096 212 213 static struct fmtpattern 214 { 215 char_u convchar; 216 char *pattern; 217 } fmt_pat[FMT_PATTERNS] = 218 { 219 {'f', ".\\+"}, // only used when at end 220 {'n', "\\d\\+"}, 221 {'l', "\\d\\+"}, 222 {'c', "\\d\\+"}, 223 {'t', "."}, 224 {'m', ".\\+"}, 225 {'r', ".*"}, 226 {'p', "[- .]*"}, 227 {'v', "\\d\\+"}, 228 {'s', ".\\+"}, 229 {'o', ".\\+"} 230 }; 231 232 /* 233 * Convert an errorformat pattern to a regular expression pattern. 234 * See fmt_pat definition above for the list of supported patterns. The 235 * pattern specifier is supplied in "efmpat". The converted pattern is stored 236 * in "regpat". Returns a pointer to the location after the pattern. 237 */ 238 static char_u * 239 efmpat_to_regpat( 240 char_u *efmpat, 241 char_u *regpat, 242 efm_T *efminfo, 243 int idx, 244 int round) 245 { 246 char_u *srcptr; 247 248 if (efminfo->addr[idx]) 249 { 250 // Each errorformat pattern can occur only once 251 semsg(_("E372: Too many %%%c in format string"), *efmpat); 252 return NULL; 253 } 254 if ((idx && idx < 6 255 && vim_strchr((char_u *)"DXOPQ", efminfo->prefix) != NULL) 256 || (idx == 6 257 && vim_strchr((char_u *)"OPQ", efminfo->prefix) == NULL)) 258 { 259 semsg(_("E373: Unexpected %%%c in format string"), *efmpat); 260 return NULL; 261 } 262 efminfo->addr[idx] = (char_u)++round; 263 *regpat++ = '\\'; 264 *regpat++ = '('; 265 #ifdef BACKSLASH_IN_FILENAME 266 if (*efmpat == 'f') 267 { 268 // Also match "c:" in the file name, even when 269 // checking for a colon next: "%f:". 270 // "\%(\a:\)\=" 271 STRCPY(regpat, "\\%(\\a:\\)\\="); 272 regpat += 10; 273 } 274 #endif 275 if (*efmpat == 'f' && efmpat[1] != NUL) 276 { 277 if (efmpat[1] != '\\' && efmpat[1] != '%') 278 { 279 // A file name may contain spaces, but this isn't 280 // in "\f". For "%f:%l:%m" there may be a ":" in 281 // the file name. Use ".\{-1,}x" instead (x is 282 // the next character), the requirement that :999: 283 // follows should work. 284 STRCPY(regpat, ".\\{-1,}"); 285 regpat += 7; 286 } 287 else 288 { 289 // File name followed by '\\' or '%': include as 290 // many file name chars as possible. 291 STRCPY(regpat, "\\f\\+"); 292 regpat += 4; 293 } 294 } 295 else 296 { 297 srcptr = (char_u *)fmt_pat[idx].pattern; 298 while ((*regpat = *srcptr++) != NUL) 299 ++regpat; 300 } 301 *regpat++ = '\\'; 302 *regpat++ = ')'; 303 304 return regpat; 305 } 306 307 /* 308 * Convert a scanf like format in 'errorformat' to a regular expression. 309 * Returns a pointer to the location after the pattern. 310 */ 311 static char_u * 312 scanf_fmt_to_regpat( 313 char_u **pefmp, 314 char_u *efm, 315 int len, 316 char_u *regpat) 317 { 318 char_u *efmp = *pefmp; 319 320 if (*efmp == '[' || *efmp == '\\') 321 { 322 if ((*regpat++ = *efmp) == '[') // %*[^a-z0-9] etc. 323 { 324 if (efmp[1] == '^') 325 *regpat++ = *++efmp; 326 if (efmp < efm + len) 327 { 328 *regpat++ = *++efmp; // could be ']' 329 while (efmp < efm + len 330 && (*regpat++ = *++efmp) != ']') 331 // skip ; 332 if (efmp == efm + len) 333 { 334 emsg(_("E374: Missing ] in format string")); 335 return NULL; 336 } 337 } 338 } 339 else if (efmp < efm + len) // %*\D, %*\s etc. 340 *regpat++ = *++efmp; 341 *regpat++ = '\\'; 342 *regpat++ = '+'; 343 } 344 else 345 { 346 // TODO: scanf()-like: %*ud, %*3c, %*f, ... ? 347 semsg(_("E375: Unsupported %%%c in format string"), *efmp); 348 return NULL; 349 } 350 351 *pefmp = efmp; 352 353 return regpat; 354 } 355 356 /* 357 * Analyze/parse an errorformat prefix. 358 */ 359 static char_u * 360 efm_analyze_prefix(char_u *efmp, efm_T *efminfo) 361 { 362 if (vim_strchr((char_u *)"+-", *efmp) != NULL) 363 efminfo->flags = *efmp++; 364 if (vim_strchr((char_u *)"DXAEWICZGOPQ", *efmp) != NULL) 365 efminfo->prefix = *efmp; 366 else 367 { 368 semsg(_("E376: Invalid %%%c in format string prefix"), *efmp); 369 return NULL; 370 } 371 372 return efmp; 373 } 374 375 /* 376 * Converts a 'errorformat' string part in 'efm' to a regular expression 377 * pattern. The resulting regex pattern is returned in "regpat". Additional 378 * information about the 'erroformat' pattern is returned in "fmt_ptr". 379 * Returns OK or FAIL. 380 */ 381 static int 382 efm_to_regpat( 383 char_u *efm, 384 int len, 385 efm_T *fmt_ptr, 386 char_u *regpat) 387 { 388 char_u *ptr; 389 char_u *efmp; 390 int round; 391 int idx = 0; 392 393 // Build a regexp pattern for a 'errorformat' option part 394 ptr = regpat; 395 *ptr++ = '^'; 396 round = 0; 397 for (efmp = efm; efmp < efm + len; ++efmp) 398 { 399 if (*efmp == '%') 400 { 401 ++efmp; 402 for (idx = 0; idx < FMT_PATTERNS; ++idx) 403 if (fmt_pat[idx].convchar == *efmp) 404 break; 405 if (idx < FMT_PATTERNS) 406 { 407 ptr = efmpat_to_regpat(efmp, ptr, fmt_ptr, idx, round); 408 if (ptr == NULL) 409 return FAIL; 410 round++; 411 } 412 else if (*efmp == '*') 413 { 414 ++efmp; 415 ptr = scanf_fmt_to_regpat(&efmp, efm, len, ptr); 416 if (ptr == NULL) 417 return FAIL; 418 } 419 else if (vim_strchr((char_u *)"%\\.^$~[", *efmp) != NULL) 420 *ptr++ = *efmp; // regexp magic characters 421 else if (*efmp == '#') 422 *ptr++ = '*'; 423 else if (*efmp == '>') 424 fmt_ptr->conthere = TRUE; 425 else if (efmp == efm + 1) // analyse prefix 426 { 427 // prefix is allowed only at the beginning of the errorformat 428 // option part 429 efmp = efm_analyze_prefix(efmp, fmt_ptr); 430 if (efmp == NULL) 431 return FAIL; 432 } 433 else 434 { 435 semsg(_("E377: Invalid %%%c in format string"), *efmp); 436 return FAIL; 437 } 438 } 439 else // copy normal character 440 { 441 if (*efmp == '\\' && efmp + 1 < efm + len) 442 ++efmp; 443 else if (vim_strchr((char_u *)".*^$~[", *efmp) != NULL) 444 *ptr++ = '\\'; // escape regexp atoms 445 if (*efmp) 446 *ptr++ = *efmp; 447 } 448 } 449 *ptr++ = '$'; 450 *ptr = NUL; 451 452 return OK; 453 } 454 455 /* 456 * Free the 'errorformat' information list 457 */ 458 static void 459 free_efm_list(efm_T **efm_first) 460 { 461 efm_T *efm_ptr; 462 463 for (efm_ptr = *efm_first; efm_ptr != NULL; efm_ptr = *efm_first) 464 { 465 *efm_first = efm_ptr->next; 466 vim_regfree(efm_ptr->prog); 467 vim_free(efm_ptr); 468 } 469 fmt_start = NULL; 470 } 471 472 /* 473 * Compute the size of the buffer used to convert a 'errorformat' pattern into 474 * a regular expression pattern. 475 */ 476 static int 477 efm_regpat_bufsz(char_u *efm) 478 { 479 int sz; 480 int i; 481 482 sz = (FMT_PATTERNS * 3) + ((int)STRLEN(efm) << 2); 483 for (i = FMT_PATTERNS; i > 0; ) 484 sz += (int)STRLEN(fmt_pat[--i].pattern); 485 #ifdef BACKSLASH_IN_FILENAME 486 sz += 12; // "%f" can become twelve chars longer (see efm_to_regpat) 487 #else 488 sz += 2; // "%f" can become two chars longer 489 #endif 490 491 return sz; 492 } 493 494 /* 495 * Return the length of a 'errorformat' option part (separated by ","). 496 */ 497 static int 498 efm_option_part_len(char_u *efm) 499 { 500 int len; 501 502 for (len = 0; efm[len] != NUL && efm[len] != ','; ++len) 503 if (efm[len] == '\\' && efm[len + 1] != NUL) 504 ++len; 505 506 return len; 507 } 508 509 /* 510 * Parse the 'errorformat' option. Multiple parts in the 'errorformat' option 511 * are parsed and converted to regular expressions. Returns information about 512 * the parsed 'errorformat' option. 513 */ 514 static efm_T * 515 parse_efm_option(char_u *efm) 516 { 517 efm_T *fmt_ptr = NULL; 518 efm_T *fmt_first = NULL; 519 efm_T *fmt_last = NULL; 520 char_u *fmtstr = NULL; 521 int len; 522 int sz; 523 524 // Each part of the format string is copied and modified from errorformat 525 // to regex prog. Only a few % characters are allowed. 526 527 // Get some space to modify the format string into. 528 sz = efm_regpat_bufsz(efm); 529 if ((fmtstr = alloc(sz)) == NULL) 530 goto parse_efm_error; 531 532 while (efm[0] != NUL) 533 { 534 // Allocate a new eformat structure and put it at the end of the list 535 fmt_ptr = (efm_T *)alloc_clear((unsigned)sizeof(efm_T)); 536 if (fmt_ptr == NULL) 537 goto parse_efm_error; 538 if (fmt_first == NULL) // first one 539 fmt_first = fmt_ptr; 540 else 541 fmt_last->next = fmt_ptr; 542 fmt_last = fmt_ptr; 543 544 // Isolate one part in the 'errorformat' option 545 len = efm_option_part_len(efm); 546 547 if (efm_to_regpat(efm, len, fmt_ptr, fmtstr) == FAIL) 548 goto parse_efm_error; 549 if ((fmt_ptr->prog = vim_regcomp(fmtstr, RE_MAGIC + RE_STRING)) == NULL) 550 goto parse_efm_error; 551 // Advance to next part 552 efm = skip_to_option_part(efm + len); // skip comma and spaces 553 } 554 555 if (fmt_first == NULL) // nothing found 556 emsg(_("E378: 'errorformat' contains no pattern")); 557 558 goto parse_efm_end; 559 560 parse_efm_error: 561 free_efm_list(&fmt_first); 562 563 parse_efm_end: 564 vim_free(fmtstr); 565 566 return fmt_first; 567 } 568 569 enum { 570 QF_FAIL = 0, 571 QF_OK = 1, 572 QF_END_OF_INPUT = 2, 573 QF_NOMEM = 3, 574 QF_IGNORE_LINE = 4, 575 QF_MULTISCAN = 5, 576 }; 577 578 /* 579 * State information used to parse lines and add entries to a quickfix/location 580 * list. 581 */ 582 typedef struct { 583 char_u *linebuf; 584 int linelen; 585 char_u *growbuf; 586 int growbufsiz; 587 FILE *fd; 588 typval_T *tv; 589 char_u *p_str; 590 listitem_T *p_li; 591 buf_T *buf; 592 linenr_T buflnum; 593 linenr_T lnumlast; 594 vimconv_T vc; 595 } qfstate_T; 596 597 /* 598 * Allocate more memory for the line buffer used for parsing lines. 599 */ 600 static char_u * 601 qf_grow_linebuf(qfstate_T *state, int newsz) 602 { 603 char_u *p; 604 605 // If the line exceeds LINE_MAXLEN exclude the last 606 // byte since it's not a NL character. 607 state->linelen = newsz > LINE_MAXLEN ? LINE_MAXLEN - 1 : newsz; 608 if (state->growbuf == NULL) 609 { 610 state->growbuf = alloc(state->linelen + 1); 611 if (state->growbuf == NULL) 612 return NULL; 613 state->growbufsiz = state->linelen; 614 } 615 else if (state->linelen > state->growbufsiz) 616 { 617 if ((p = vim_realloc(state->growbuf, state->linelen + 1)) == NULL) 618 return NULL; 619 state->growbuf = p; 620 state->growbufsiz = state->linelen; 621 } 622 return state->growbuf; 623 } 624 625 /* 626 * Get the next string (separated by newline) from state->p_str. 627 */ 628 static int 629 qf_get_next_str_line(qfstate_T *state) 630 { 631 // Get the next line from the supplied string 632 char_u *p_str = state->p_str; 633 char_u *p; 634 int len; 635 636 if (*p_str == NUL) // Reached the end of the string 637 return QF_END_OF_INPUT; 638 639 p = vim_strchr(p_str, '\n'); 640 if (p != NULL) 641 len = (int)(p - p_str) + 1; 642 else 643 len = (int)STRLEN(p_str); 644 645 if (len > IOSIZE - 2) 646 { 647 state->linebuf = qf_grow_linebuf(state, len); 648 if (state->linebuf == NULL) 649 return QF_NOMEM; 650 } 651 else 652 { 653 state->linebuf = IObuff; 654 state->linelen = len; 655 } 656 vim_strncpy(state->linebuf, p_str, state->linelen); 657 658 // Increment using len in order to discard the rest of the 659 // line if it exceeds LINE_MAXLEN. 660 p_str += len; 661 state->p_str = p_str; 662 663 return QF_OK; 664 } 665 666 /* 667 * Get the next string from state->p_Li. 668 */ 669 static int 670 qf_get_next_list_line(qfstate_T *state) 671 { 672 listitem_T *p_li = state->p_li; 673 int len; 674 675 while (p_li != NULL 676 && (p_li->li_tv.v_type != VAR_STRING 677 || p_li->li_tv.vval.v_string == NULL)) 678 p_li = p_li->li_next; // Skip non-string items 679 680 if (p_li == NULL) // End of the list 681 { 682 state->p_li = NULL; 683 return QF_END_OF_INPUT; 684 } 685 686 len = (int)STRLEN(p_li->li_tv.vval.v_string); 687 if (len > IOSIZE - 2) 688 { 689 state->linebuf = qf_grow_linebuf(state, len); 690 if (state->linebuf == NULL) 691 return QF_NOMEM; 692 } 693 else 694 { 695 state->linebuf = IObuff; 696 state->linelen = len; 697 } 698 699 vim_strncpy(state->linebuf, p_li->li_tv.vval.v_string, state->linelen); 700 701 state->p_li = p_li->li_next; // next item 702 return QF_OK; 703 } 704 705 /* 706 * Get the next string from state->buf. 707 */ 708 static int 709 qf_get_next_buf_line(qfstate_T *state) 710 { 711 char_u *p_buf = NULL; 712 int len; 713 714 // Get the next line from the supplied buffer 715 if (state->buflnum > state->lnumlast) 716 return QF_END_OF_INPUT; 717 718 p_buf = ml_get_buf(state->buf, state->buflnum, FALSE); 719 state->buflnum += 1; 720 721 len = (int)STRLEN(p_buf); 722 if (len > IOSIZE - 2) 723 { 724 state->linebuf = qf_grow_linebuf(state, len); 725 if (state->linebuf == NULL) 726 return QF_NOMEM; 727 } 728 else 729 { 730 state->linebuf = IObuff; 731 state->linelen = len; 732 } 733 vim_strncpy(state->linebuf, p_buf, state->linelen); 734 735 return QF_OK; 736 } 737 738 /* 739 * Get the next string from file state->fd. 740 */ 741 static int 742 qf_get_next_file_line(qfstate_T *state) 743 { 744 int discard; 745 int growbuflen; 746 747 if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL) 748 return QF_END_OF_INPUT; 749 750 discard = FALSE; 751 state->linelen = (int)STRLEN(IObuff); 752 if (state->linelen == IOSIZE - 1 && !(IObuff[state->linelen - 1] == '\n')) 753 { 754 // The current line exceeds IObuff, continue reading using 755 // growbuf until EOL or LINE_MAXLEN bytes is read. 756 if (state->growbuf == NULL) 757 { 758 state->growbufsiz = 2 * (IOSIZE - 1); 759 state->growbuf = alloc(state->growbufsiz); 760 if (state->growbuf == NULL) 761 return QF_NOMEM; 762 } 763 764 // Copy the read part of the line, excluding null-terminator 765 memcpy(state->growbuf, IObuff, IOSIZE - 1); 766 growbuflen = state->linelen; 767 768 for (;;) 769 { 770 char_u *p; 771 772 if (fgets((char *)state->growbuf + growbuflen, 773 state->growbufsiz - growbuflen, state->fd) == NULL) 774 break; 775 state->linelen = (int)STRLEN(state->growbuf + growbuflen); 776 growbuflen += state->linelen; 777 if ((state->growbuf)[growbuflen - 1] == '\n') 778 break; 779 if (state->growbufsiz == LINE_MAXLEN) 780 { 781 discard = TRUE; 782 break; 783 } 784 785 state->growbufsiz = 2 * state->growbufsiz < LINE_MAXLEN 786 ? 2 * state->growbufsiz : LINE_MAXLEN; 787 if ((p = vim_realloc(state->growbuf, state->growbufsiz)) == NULL) 788 return QF_NOMEM; 789 state->growbuf = p; 790 } 791 792 while (discard) 793 { 794 // The current line is longer than LINE_MAXLEN, continue 795 // reading but discard everything until EOL or EOF is 796 // reached. 797 if (fgets((char *)IObuff, IOSIZE, state->fd) == NULL 798 || (int)STRLEN(IObuff) < IOSIZE - 1 799 || IObuff[IOSIZE - 1] == '\n') 800 break; 801 } 802 803 state->linebuf = state->growbuf; 804 state->linelen = growbuflen; 805 } 806 else 807 state->linebuf = IObuff; 808 809 // Convert a line if it contains a non-ASCII character. 810 if (state->vc.vc_type != CONV_NONE && has_non_ascii(state->linebuf)) 811 { 812 char_u *line; 813 814 line = string_convert(&state->vc, state->linebuf, &state->linelen); 815 if (line != NULL) 816 { 817 if (state->linelen < IOSIZE) 818 { 819 STRCPY(state->linebuf, line); 820 vim_free(line); 821 } 822 else 823 { 824 vim_free(state->growbuf); 825 state->linebuf = state->growbuf = line; 826 state->growbufsiz = state->linelen < LINE_MAXLEN 827 ? state->linelen : LINE_MAXLEN; 828 } 829 } 830 } 831 832 return QF_OK; 833 } 834 835 /* 836 * Get the next string from a file/buffer/list/string. 837 */ 838 static int 839 qf_get_nextline(qfstate_T *state) 840 { 841 int status = QF_FAIL; 842 843 if (state->fd == NULL) 844 { 845 if (state->tv != NULL) 846 { 847 if (state->tv->v_type == VAR_STRING) 848 // Get the next line from the supplied string 849 status = qf_get_next_str_line(state); 850 else if (state->tv->v_type == VAR_LIST) 851 // Get the next line from the supplied list 852 status = qf_get_next_list_line(state); 853 } 854 else 855 // Get the next line from the supplied buffer 856 status = qf_get_next_buf_line(state); 857 } 858 else 859 // Get the next line from the supplied file 860 status = qf_get_next_file_line(state); 861 862 if (status != QF_OK) 863 return status; 864 865 // remove newline/CR from the line 866 if (state->linelen > 0 && state->linebuf[state->linelen - 1] == '\n') 867 { 868 state->linebuf[state->linelen - 1] = NUL; 869 #ifdef USE_CRNL 870 if (state->linelen > 1 && state->linebuf[state->linelen - 2] == '\r') 871 state->linebuf[state->linelen - 2] = NUL; 872 #endif 873 } 874 875 remove_bom(state->linebuf); 876 877 return QF_OK; 878 } 879 880 typedef struct { 881 char_u *namebuf; 882 char_u *module; 883 char_u *errmsg; 884 int errmsglen; 885 long lnum; 886 int col; 887 char_u use_viscol; 888 char_u *pattern; 889 int enr; 890 int type; 891 int valid; 892 } qffields_T; 893 894 /* 895 * Parse the match for filename ('%f') pattern in regmatch. 896 * Return the matched value in "fields->namebuf". 897 */ 898 static int 899 qf_parse_fmt_f(regmatch_T *rmp, int midx, qffields_T *fields, int prefix) 900 { 901 int c; 902 903 if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) 904 return QF_FAIL; 905 906 // Expand ~/file and $HOME/file to full path. 907 c = *rmp->endp[midx]; 908 *rmp->endp[midx] = NUL; 909 expand_env(rmp->startp[midx], fields->namebuf, CMDBUFFSIZE); 910 *rmp->endp[midx] = c; 911 912 // For separate filename patterns (%O, %P and %Q), the specified file 913 // should exist. 914 if (vim_strchr((char_u *)"OPQ", prefix) != NULL 915 && mch_getperm(fields->namebuf) == -1) 916 return QF_FAIL; 917 918 return QF_OK; 919 } 920 921 /* 922 * Parse the match for error number ('%n') pattern in regmatch. 923 * Return the matched value in "fields->enr". 924 */ 925 static int 926 qf_parse_fmt_n(regmatch_T *rmp, int midx, qffields_T *fields) 927 { 928 if (rmp->startp[midx] == NULL) 929 return QF_FAIL; 930 fields->enr = (int)atol((char *)rmp->startp[midx]); 931 return QF_OK; 932 } 933 934 /* 935 * Parse the match for line number (%l') pattern in regmatch. 936 * Return the matched value in "fields->lnum". 937 */ 938 static int 939 qf_parse_fmt_l(regmatch_T *rmp, int midx, qffields_T *fields) 940 { 941 if (rmp->startp[midx] == NULL) 942 return QF_FAIL; 943 fields->lnum = atol((char *)rmp->startp[midx]); 944 return QF_OK; 945 } 946 947 /* 948 * Parse the match for column number ('%c') pattern in regmatch. 949 * Return the matched value in "fields->col". 950 */ 951 static int 952 qf_parse_fmt_c(regmatch_T *rmp, int midx, qffields_T *fields) 953 { 954 if (rmp->startp[midx] == NULL) 955 return QF_FAIL; 956 fields->col = (int)atol((char *)rmp->startp[midx]); 957 return QF_OK; 958 } 959 960 /* 961 * Parse the match for error type ('%t') pattern in regmatch. 962 * Return the matched value in "fields->type". 963 */ 964 static int 965 qf_parse_fmt_t(regmatch_T *rmp, int midx, qffields_T *fields) 966 { 967 if (rmp->startp[midx] == NULL) 968 return QF_FAIL; 969 fields->type = *rmp->startp[midx]; 970 return QF_OK; 971 } 972 973 /* 974 * Parse the match for '%+' format pattern. The whole matching line is included 975 * in the error string. Return the matched line in "fields->errmsg". 976 */ 977 static int 978 qf_parse_fmt_plus(char_u *linebuf, int linelen, qffields_T *fields) 979 { 980 char_u *p; 981 982 if (linelen >= fields->errmsglen) 983 { 984 // linelen + null terminator 985 if ((p = vim_realloc(fields->errmsg, linelen + 1)) == NULL) 986 return QF_NOMEM; 987 fields->errmsg = p; 988 fields->errmsglen = linelen + 1; 989 } 990 vim_strncpy(fields->errmsg, linebuf, linelen); 991 return QF_OK; 992 } 993 994 /* 995 * Parse the match for error message ('%m') pattern in regmatch. 996 * Return the matched value in "fields->errmsg". 997 */ 998 static int 999 qf_parse_fmt_m(regmatch_T *rmp, int midx, qffields_T *fields) 1000 { 1001 char_u *p; 1002 int len; 1003 1004 if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) 1005 return QF_FAIL; 1006 len = (int)(rmp->endp[midx] - rmp->startp[midx]); 1007 if (len >= fields->errmsglen) 1008 { 1009 // len + null terminator 1010 if ((p = vim_realloc(fields->errmsg, len + 1)) == NULL) 1011 return QF_NOMEM; 1012 fields->errmsg = p; 1013 fields->errmsglen = len + 1; 1014 } 1015 vim_strncpy(fields->errmsg, rmp->startp[midx], len); 1016 return QF_OK; 1017 } 1018 1019 /* 1020 * Parse the match for rest of a single-line file message ('%r') pattern. 1021 * Return the matched value in "tail". 1022 */ 1023 static int 1024 qf_parse_fmt_r(regmatch_T *rmp, int midx, char_u **tail) 1025 { 1026 if (rmp->startp[midx] == NULL) 1027 return QF_FAIL; 1028 *tail = rmp->startp[midx]; 1029 return QF_OK; 1030 } 1031 1032 /* 1033 * Parse the match for the pointer line ('%p') pattern in regmatch. 1034 * Return the matched value in "fields->col". 1035 */ 1036 static int 1037 qf_parse_fmt_p(regmatch_T *rmp, int midx, qffields_T *fields) 1038 { 1039 char_u *match_ptr; 1040 1041 if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) 1042 return QF_FAIL; 1043 fields->col = 0; 1044 for (match_ptr = rmp->startp[midx]; match_ptr != rmp->endp[midx]; 1045 ++match_ptr) 1046 { 1047 ++fields->col; 1048 if (*match_ptr == TAB) 1049 { 1050 fields->col += 7; 1051 fields->col -= fields->col % 8; 1052 } 1053 } 1054 ++fields->col; 1055 fields->use_viscol = TRUE; 1056 return QF_OK; 1057 } 1058 1059 /* 1060 * Parse the match for the virtual column number ('%v') pattern in regmatch. 1061 * Return the matched value in "fields->col". 1062 */ 1063 static int 1064 qf_parse_fmt_v(regmatch_T *rmp, int midx, qffields_T *fields) 1065 { 1066 if (rmp->startp[midx] == NULL) 1067 return QF_FAIL; 1068 fields->col = (int)atol((char *)rmp->startp[midx]); 1069 fields->use_viscol = TRUE; 1070 return QF_OK; 1071 } 1072 1073 /* 1074 * Parse the match for the search text ('%s') pattern in regmatch. 1075 * Return the matched value in "fields->pattern". 1076 */ 1077 static int 1078 qf_parse_fmt_s(regmatch_T *rmp, int midx, qffields_T *fields) 1079 { 1080 int len; 1081 1082 if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) 1083 return QF_FAIL; 1084 len = (int)(rmp->endp[midx] - rmp->startp[midx]); 1085 if (len > CMDBUFFSIZE - 5) 1086 len = CMDBUFFSIZE - 5; 1087 STRCPY(fields->pattern, "^\\V"); 1088 STRNCAT(fields->pattern, rmp->startp[midx], len); 1089 fields->pattern[len + 3] = '\\'; 1090 fields->pattern[len + 4] = '$'; 1091 fields->pattern[len + 5] = NUL; 1092 return QF_OK; 1093 } 1094 1095 /* 1096 * Parse the match for the module ('%o') pattern in regmatch. 1097 * Return the matched value in "fields->module". 1098 */ 1099 static int 1100 qf_parse_fmt_o(regmatch_T *rmp, int midx, qffields_T *fields) 1101 { 1102 int len; 1103 1104 if (rmp->startp[midx] == NULL || rmp->endp[midx] == NULL) 1105 return QF_FAIL; 1106 len = (int)(rmp->endp[midx] - rmp->startp[midx]); 1107 if (len > CMDBUFFSIZE) 1108 len = CMDBUFFSIZE; 1109 STRNCAT(fields->module, rmp->startp[midx], len); 1110 return QF_OK; 1111 } 1112 1113 /* 1114 * 'errorformat' format pattern parser functions. 1115 * The '%f' and '%r' formats are parsed differently from other formats. 1116 * See qf_parse_match() for details. 1117 */ 1118 static int (*qf_parse_fmt[FMT_PATTERNS])(regmatch_T *, int, qffields_T *) = 1119 { 1120 NULL, 1121 qf_parse_fmt_n, 1122 qf_parse_fmt_l, 1123 qf_parse_fmt_c, 1124 qf_parse_fmt_t, 1125 qf_parse_fmt_m, 1126 NULL, 1127 qf_parse_fmt_p, 1128 qf_parse_fmt_v, 1129 qf_parse_fmt_s, 1130 qf_parse_fmt_o 1131 }; 1132 1133 /* 1134 * Parse the error format pattern matches in "regmatch" and set the values in 1135 * "fields". fmt_ptr contains the 'efm' format specifiers/prefixes that have a 1136 * match. Returns QF_OK if all the matches are successfully parsed. On 1137 * failure, returns QF_FAIL or QF_NOMEM. 1138 */ 1139 static int 1140 qf_parse_match( 1141 char_u *linebuf, 1142 int linelen, 1143 efm_T *fmt_ptr, 1144 regmatch_T *regmatch, 1145 qffields_T *fields, 1146 int qf_multiline, 1147 int qf_multiscan, 1148 char_u **tail) 1149 { 1150 int idx = fmt_ptr->prefix; 1151 int i; 1152 int midx; 1153 int status; 1154 1155 if ((idx == 'C' || idx == 'Z') && !qf_multiline) 1156 return QF_FAIL; 1157 if (vim_strchr((char_u *)"EWI", idx) != NULL) 1158 fields->type = idx; 1159 else 1160 fields->type = 0; 1161 1162 // Extract error message data from matched line. 1163 // We check for an actual submatch, because "\[" and "\]" in 1164 // the 'errorformat' may cause the wrong submatch to be used. 1165 for (i = 0; i < FMT_PATTERNS; i++) 1166 { 1167 status = QF_OK; 1168 midx = (int)fmt_ptr->addr[i]; 1169 if (i == 0 && midx > 0) // %f 1170 status = qf_parse_fmt_f(regmatch, midx, fields, idx); 1171 else if (i == 5) 1172 { 1173 if (fmt_ptr->flags == '+' && !qf_multiscan) // %+ 1174 status = qf_parse_fmt_plus(linebuf, linelen, fields); 1175 else if (midx > 0) // %m 1176 status = qf_parse_fmt_m(regmatch, midx, fields); 1177 } 1178 else if (i == 6 && midx > 0) // %r 1179 status = qf_parse_fmt_r(regmatch, midx, tail); 1180 else if (midx > 0) // others 1181 status = (qf_parse_fmt[i])(regmatch, midx, fields); 1182 1183 if (status != QF_OK) 1184 return status; 1185 } 1186 1187 return QF_OK; 1188 } 1189 1190 /* 1191 * Parse an error line in 'linebuf' using a single error format string in 1192 * 'fmt_ptr->prog' and return the matching values in 'fields'. 1193 * Returns QF_OK if the efm format matches completely and the fields are 1194 * successfully copied. Otherwise returns QF_FAIL or QF_NOMEM. 1195 */ 1196 static int 1197 qf_parse_get_fields( 1198 char_u *linebuf, 1199 int linelen, 1200 efm_T *fmt_ptr, 1201 qffields_T *fields, 1202 int qf_multiline, 1203 int qf_multiscan, 1204 char_u **tail) 1205 { 1206 regmatch_T regmatch; 1207 int status = QF_FAIL; 1208 int r; 1209 1210 if (qf_multiscan && 1211 vim_strchr((char_u *)"OPQ", fmt_ptr->prefix) == NULL) 1212 return QF_FAIL; 1213 1214 fields->namebuf[0] = NUL; 1215 fields->module[0] = NUL; 1216 fields->pattern[0] = NUL; 1217 if (!qf_multiscan) 1218 fields->errmsg[0] = NUL; 1219 fields->lnum = 0; 1220 fields->col = 0; 1221 fields->use_viscol = FALSE; 1222 fields->enr = -1; 1223 fields->type = 0; 1224 *tail = NULL; 1225 1226 // Always ignore case when looking for a matching error. 1227 regmatch.rm_ic = TRUE; 1228 regmatch.regprog = fmt_ptr->prog; 1229 r = vim_regexec(®match, linebuf, (colnr_T)0); 1230 fmt_ptr->prog = regmatch.regprog; 1231 if (r) 1232 status = qf_parse_match(linebuf, linelen, fmt_ptr, ®match, 1233 fields, qf_multiline, qf_multiscan, tail); 1234 1235 return status; 1236 } 1237 1238 /* 1239 * Parse directory error format prefixes (%D and %X). 1240 * Push and pop directories from the directory stack when scanning directory 1241 * names. 1242 */ 1243 static int 1244 qf_parse_dir_pfx(int idx, qffields_T *fields, qf_list_T *qfl) 1245 { 1246 if (idx == 'D') // enter directory 1247 { 1248 if (*fields->namebuf == NUL) 1249 { 1250 emsg(_("E379: Missing or empty directory name")); 1251 return QF_FAIL; 1252 } 1253 qfl->qf_directory = 1254 qf_push_dir(fields->namebuf, &qfl->qf_dir_stack, FALSE); 1255 if (qfl->qf_directory == NULL) 1256 return QF_FAIL; 1257 } 1258 else if (idx == 'X') // leave directory 1259 qfl->qf_directory = qf_pop_dir(&qfl->qf_dir_stack); 1260 1261 return QF_OK; 1262 } 1263 1264 /* 1265 * Parse global file name error format prefixes (%O, %P and %Q). 1266 */ 1267 static int 1268 qf_parse_file_pfx( 1269 int idx, 1270 qffields_T *fields, 1271 qf_list_T *qfl, 1272 char_u *tail) 1273 { 1274 fields->valid = FALSE; 1275 if (*fields->namebuf == NUL || mch_getperm(fields->namebuf) >= 0) 1276 { 1277 if (*fields->namebuf && idx == 'P') 1278 qfl->qf_currfile = 1279 qf_push_dir(fields->namebuf, &qfl->qf_file_stack, TRUE); 1280 else if (idx == 'Q') 1281 qfl->qf_currfile = qf_pop_dir(&qfl->qf_file_stack); 1282 *fields->namebuf = NUL; 1283 if (tail && *tail) 1284 { 1285 STRMOVE(IObuff, skipwhite(tail)); 1286 qfl->qf_multiscan = TRUE; 1287 return QF_MULTISCAN; 1288 } 1289 } 1290 1291 return QF_OK; 1292 } 1293 1294 /* 1295 * Parse a non-error line (a line which doesn't match any of the error 1296 * format in 'efm'). 1297 */ 1298 static int 1299 qf_parse_line_nomatch(char_u *linebuf, int linelen, qffields_T *fields) 1300 { 1301 char_u *p; 1302 1303 fields->namebuf[0] = NUL; // no match found, remove file name 1304 fields->lnum = 0; // don't jump to this line 1305 fields->valid = FALSE; 1306 if (linelen >= fields->errmsglen) 1307 { 1308 // linelen + null terminator 1309 if ((p = vim_realloc(fields->errmsg, linelen + 1)) == NULL) 1310 return QF_NOMEM; 1311 fields->errmsg = p; 1312 fields->errmsglen = linelen + 1; 1313 } 1314 // copy whole line to error message 1315 vim_strncpy(fields->errmsg, linebuf, linelen); 1316 1317 return QF_OK; 1318 } 1319 1320 /* 1321 * Parse multi-line error format prefixes (%C and %Z) 1322 */ 1323 static int 1324 qf_parse_multiline_pfx( 1325 qf_info_T *qi, 1326 int qf_idx, 1327 int idx, 1328 qf_list_T *qfl, 1329 qffields_T *fields) 1330 { 1331 char_u *ptr; 1332 int len; 1333 1334 if (!qfl->qf_multiignore) 1335 { 1336 qfline_T *qfprev = qfl->qf_last; 1337 1338 if (qfprev == NULL) 1339 return QF_FAIL; 1340 if (*fields->errmsg && !qfl->qf_multiignore) 1341 { 1342 len = (int)STRLEN(qfprev->qf_text); 1343 if ((ptr = alloc((unsigned)(len + STRLEN(fields->errmsg) + 2))) 1344 == NULL) 1345 return QF_FAIL; 1346 STRCPY(ptr, qfprev->qf_text); 1347 vim_free(qfprev->qf_text); 1348 qfprev->qf_text = ptr; 1349 *(ptr += len) = '\n'; 1350 STRCPY(++ptr, fields->errmsg); 1351 } 1352 if (qfprev->qf_nr == -1) 1353 qfprev->qf_nr = fields->enr; 1354 if (vim_isprintc(fields->type) && !qfprev->qf_type) 1355 // only printable chars allowed 1356 qfprev->qf_type = fields->type; 1357 1358 if (!qfprev->qf_lnum) 1359 qfprev->qf_lnum = fields->lnum; 1360 if (!qfprev->qf_col) 1361 qfprev->qf_col = fields->col; 1362 qfprev->qf_viscol = fields->use_viscol; 1363 if (!qfprev->qf_fnum) 1364 qfprev->qf_fnum = qf_get_fnum(qi, qf_idx, 1365 qfl->qf_directory, 1366 *fields->namebuf || qfl->qf_directory != NULL 1367 ? fields->namebuf 1368 : qfl->qf_currfile != NULL && fields->valid 1369 ? qfl->qf_currfile : 0); 1370 } 1371 if (idx == 'Z') 1372 qfl->qf_multiline = qfl->qf_multiignore = FALSE; 1373 line_breakcheck(); 1374 1375 return QF_IGNORE_LINE; 1376 } 1377 1378 /* 1379 * Parse a line and get the quickfix fields. 1380 * Return the QF_ status. 1381 */ 1382 static int 1383 qf_parse_line( 1384 qf_info_T *qi, 1385 int qf_idx, 1386 char_u *linebuf, 1387 int linelen, 1388 efm_T *fmt_first, 1389 qffields_T *fields) 1390 { 1391 efm_T *fmt_ptr; 1392 int idx = 0; 1393 char_u *tail = NULL; 1394 qf_list_T *qfl = &qi->qf_lists[qf_idx]; 1395 int status; 1396 1397 restofline: 1398 // If there was no %> item start at the first pattern 1399 if (fmt_start == NULL) 1400 fmt_ptr = fmt_first; 1401 else 1402 { 1403 // Otherwise start from the last used pattern 1404 fmt_ptr = fmt_start; 1405 fmt_start = NULL; 1406 } 1407 1408 // Try to match each part of 'errorformat' until we find a complete 1409 // match or no match. 1410 fields->valid = TRUE; 1411 for ( ; fmt_ptr != NULL; fmt_ptr = fmt_ptr->next) 1412 { 1413 idx = fmt_ptr->prefix; 1414 status = qf_parse_get_fields(linebuf, linelen, fmt_ptr, fields, 1415 qfl->qf_multiline, qfl->qf_multiscan, &tail); 1416 if (status == QF_NOMEM) 1417 return status; 1418 if (status == QF_OK) 1419 break; 1420 } 1421 qfl->qf_multiscan = FALSE; 1422 1423 if (fmt_ptr == NULL || idx == 'D' || idx == 'X') 1424 { 1425 if (fmt_ptr != NULL) 1426 { 1427 // 'D' and 'X' directory specifiers 1428 status = qf_parse_dir_pfx(idx, fields, qfl); 1429 if (status != QF_OK) 1430 return status; 1431 } 1432 1433 status = qf_parse_line_nomatch(linebuf, linelen, fields); 1434 if (status != QF_OK) 1435 return status; 1436 1437 if (fmt_ptr == NULL) 1438 qfl->qf_multiline = qfl->qf_multiignore = FALSE; 1439 } 1440 else if (fmt_ptr != NULL) 1441 { 1442 // honor %> item 1443 if (fmt_ptr->conthere) 1444 fmt_start = fmt_ptr; 1445 1446 if (vim_strchr((char_u *)"AEWI", idx) != NULL) 1447 { 1448 qfl->qf_multiline = TRUE; // start of a multi-line message 1449 qfl->qf_multiignore = FALSE;// reset continuation 1450 } 1451 else if (vim_strchr((char_u *)"CZ", idx) != NULL) 1452 { // continuation of multi-line msg 1453 status = qf_parse_multiline_pfx(qi, qf_idx, idx, qfl, fields); 1454 if (status != QF_OK) 1455 return status; 1456 } 1457 else if (vim_strchr((char_u *)"OPQ", idx) != NULL) 1458 { // global file names 1459 status = qf_parse_file_pfx(idx, fields, qfl, tail); 1460 if (status == QF_MULTISCAN) 1461 goto restofline; 1462 } 1463 if (fmt_ptr->flags == '-') // generally exclude this line 1464 { 1465 if (qfl->qf_multiline) 1466 // also exclude continuation lines 1467 qfl->qf_multiignore = TRUE; 1468 return QF_IGNORE_LINE; 1469 } 1470 } 1471 1472 return QF_OK; 1473 } 1474 1475 /* 1476 * Returns TRUE if the specified quickfix/location stack is empty 1477 */ 1478 static int 1479 qf_stack_empty(qf_info_T *qi) 1480 { 1481 return qi == NULL || qi->qf_listcount <= 0; 1482 } 1483 1484 /* 1485 * Returns TRUE if the specified quickfix/location list is empty. 1486 */ 1487 static int 1488 qf_list_empty(qf_info_T *qi, int qf_idx) 1489 { 1490 if (qi == NULL || qf_idx < 0 || qf_idx >= LISTCOUNT) 1491 return TRUE; 1492 return qi->qf_lists[qf_idx].qf_count <= 0; 1493 } 1494 1495 /* 1496 * Allocate the fields used for parsing lines and populating a quickfix list. 1497 */ 1498 static int 1499 qf_alloc_fields(qffields_T *pfields) 1500 { 1501 pfields->namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf); 1502 pfields->module = alloc_id(CMDBUFFSIZE + 1, aid_qf_module); 1503 pfields->errmsglen = CMDBUFFSIZE + 1; 1504 pfields->errmsg = alloc_id(pfields->errmsglen, aid_qf_errmsg); 1505 pfields->pattern = alloc_id(CMDBUFFSIZE + 1, aid_qf_pattern); 1506 if (pfields->namebuf == NULL || pfields->errmsg == NULL 1507 || pfields->pattern == NULL || pfields->module == NULL) 1508 return FAIL; 1509 1510 return OK; 1511 } 1512 1513 /* 1514 * Free the fields used for parsing lines and populating a quickfix list. 1515 */ 1516 static void 1517 qf_free_fields(qffields_T *pfields) 1518 { 1519 vim_free(pfields->namebuf); 1520 vim_free(pfields->module); 1521 vim_free(pfields->errmsg); 1522 vim_free(pfields->pattern); 1523 } 1524 1525 /* 1526 * Setup the state information used for parsing lines and populating a 1527 * quickfix list. 1528 */ 1529 static int 1530 qf_setup_state( 1531 qfstate_T *pstate, 1532 char_u *enc, 1533 char_u *efile, 1534 typval_T *tv, 1535 buf_T *buf, 1536 linenr_T lnumfirst, 1537 linenr_T lnumlast) 1538 { 1539 pstate->vc.vc_type = CONV_NONE; 1540 if (enc != NULL && *enc != NUL) 1541 convert_setup(&pstate->vc, enc, p_enc); 1542 1543 if (efile != NULL && (pstate->fd = mch_fopen((char *)efile, "r")) == NULL) 1544 { 1545 semsg(_(e_openerrf), efile); 1546 return FAIL; 1547 } 1548 1549 if (tv != NULL) 1550 { 1551 if (tv->v_type == VAR_STRING) 1552 pstate->p_str = tv->vval.v_string; 1553 else if (tv->v_type == VAR_LIST) 1554 pstate->p_li = tv->vval.v_list->lv_first; 1555 pstate->tv = tv; 1556 } 1557 pstate->buf = buf; 1558 pstate->buflnum = lnumfirst; 1559 pstate->lnumlast = lnumlast; 1560 1561 return OK; 1562 } 1563 1564 /* 1565 * Cleanup the state information used for parsing lines and populating a 1566 * quickfix list. 1567 */ 1568 static void 1569 qf_cleanup_state(qfstate_T *pstate) 1570 { 1571 if (pstate->fd != NULL) 1572 fclose(pstate->fd); 1573 1574 vim_free(pstate->growbuf); 1575 if (pstate->vc.vc_type != CONV_NONE) 1576 convert_setup(&pstate->vc, NULL, NULL); 1577 } 1578 1579 /* 1580 * Read the errorfile "efile" into memory, line by line, building the error 1581 * list. 1582 * Alternative: when "efile" is NULL read errors from buffer "buf". 1583 * Alternative: when "tv" is not NULL get errors from the string or list. 1584 * Always use 'errorformat' from "buf" if there is a local value. 1585 * Then "lnumfirst" and "lnumlast" specify the range of lines to use. 1586 * Set the title of the list to "qf_title". 1587 * Return -1 for error, number of errors for success. 1588 */ 1589 static int 1590 qf_init_ext( 1591 qf_info_T *qi, 1592 int qf_idx, 1593 char_u *efile, 1594 buf_T *buf, 1595 typval_T *tv, 1596 char_u *errorformat, 1597 int newlist, // TRUE: start a new error list 1598 linenr_T lnumfirst, // first line number to use 1599 linenr_T lnumlast, // last line number to use 1600 char_u *qf_title, 1601 char_u *enc) 1602 { 1603 qf_list_T *qfl; 1604 qfstate_T state; 1605 qffields_T fields; 1606 qfline_T *old_last = NULL; 1607 int adding = FALSE; 1608 static efm_T *fmt_first = NULL; 1609 char_u *efm; 1610 static char_u *last_efm = NULL; 1611 int retval = -1; // default: return error flag 1612 int status; 1613 1614 // Do not used the cached buffer, it may have been wiped out. 1615 VIM_CLEAR(qf_last_bufname); 1616 1617 vim_memset(&state, 0, sizeof(state)); 1618 vim_memset(&fields, 0, sizeof(fields)); 1619 if ((qf_alloc_fields(&fields) == FAIL) || 1620 (qf_setup_state(&state, enc, efile, tv, buf, 1621 lnumfirst, lnumlast) == FAIL)) 1622 goto qf_init_end; 1623 1624 if (newlist || qf_idx == qi->qf_listcount) 1625 { 1626 // make place for a new list 1627 qf_new_list(qi, qf_title); 1628 qf_idx = qi->qf_curlist; 1629 } 1630 else 1631 { 1632 // Adding to existing list, use last entry. 1633 adding = TRUE; 1634 if (!qf_list_empty(qi, qf_idx)) 1635 old_last = qi->qf_lists[qf_idx].qf_last; 1636 } 1637 1638 qfl = &qi->qf_lists[qf_idx]; 1639 1640 // Use the local value of 'errorformat' if it's set. 1641 if (errorformat == p_efm && tv == NULL && *buf->b_p_efm != NUL) 1642 efm = buf->b_p_efm; 1643 else 1644 efm = errorformat; 1645 1646 // If the errorformat didn't change between calls, then reuse the 1647 // previously parsed values. 1648 if (last_efm == NULL || (STRCMP(last_efm, efm) != 0)) 1649 { 1650 // free the previously parsed data 1651 VIM_CLEAR(last_efm); 1652 free_efm_list(&fmt_first); 1653 1654 // parse the current 'efm' 1655 fmt_first = parse_efm_option(efm); 1656 if (fmt_first != NULL) 1657 last_efm = vim_strsave(efm); 1658 } 1659 1660 if (fmt_first == NULL) // nothing found 1661 goto error2; 1662 1663 // got_int is reset here, because it was probably set when killing the 1664 // ":make" command, but we still want to read the errorfile then. 1665 got_int = FALSE; 1666 1667 // Read the lines in the error file one by one. 1668 // Try to recognize one of the error formats in each line. 1669 while (!got_int) 1670 { 1671 // Get the next line from a file/buffer/list/string 1672 status = qf_get_nextline(&state); 1673 if (status == QF_NOMEM) // memory alloc failure 1674 goto qf_init_end; 1675 if (status == QF_END_OF_INPUT) // end of input 1676 break; 1677 1678 status = qf_parse_line(qi, qf_idx, state.linebuf, state.linelen, 1679 fmt_first, &fields); 1680 if (status == QF_FAIL) 1681 goto error2; 1682 if (status == QF_NOMEM) 1683 goto qf_init_end; 1684 if (status == QF_IGNORE_LINE) 1685 continue; 1686 1687 if (qf_add_entry(qi, 1688 qf_idx, 1689 qfl->qf_directory, 1690 (*fields.namebuf || qfl->qf_directory != NULL) 1691 ? fields.namebuf 1692 : ((qfl->qf_currfile != NULL && fields.valid) 1693 ? qfl->qf_currfile : (char_u *)NULL), 1694 fields.module, 1695 0, 1696 fields.errmsg, 1697 fields.lnum, 1698 fields.col, 1699 fields.use_viscol, 1700 fields.pattern, 1701 fields.enr, 1702 fields.type, 1703 fields.valid) == FAIL) 1704 goto error2; 1705 line_breakcheck(); 1706 } 1707 if (state.fd == NULL || !ferror(state.fd)) 1708 { 1709 if (qfl->qf_index == 0) 1710 { 1711 // no valid entry found 1712 qfl->qf_ptr = qfl->qf_start; 1713 qfl->qf_index = 1; 1714 qfl->qf_nonevalid = TRUE; 1715 } 1716 else 1717 { 1718 qfl->qf_nonevalid = FALSE; 1719 if (qfl->qf_ptr == NULL) 1720 qfl->qf_ptr = qfl->qf_start; 1721 } 1722 // return number of matches 1723 retval = qfl->qf_count; 1724 goto qf_init_end; 1725 } 1726 emsg(_(e_readerrf)); 1727 error2: 1728 if (!adding) 1729 { 1730 // Error when creating a new list. Free the new list 1731 qf_free(qfl); 1732 qi->qf_listcount--; 1733 if (qi->qf_curlist > 0) 1734 --qi->qf_curlist; 1735 } 1736 qf_init_end: 1737 if (qf_idx == qi->qf_curlist) 1738 qf_update_buffer(qi, old_last); 1739 qf_cleanup_state(&state); 1740 qf_free_fields(&fields); 1741 1742 return retval; 1743 } 1744 1745 /* 1746 * Read the errorfile "efile" into memory, line by line, building the error 1747 * list. Set the error list's title to qf_title. 1748 * Return -1 for error, number of errors for success. 1749 */ 1750 int 1751 qf_init(win_T *wp, 1752 char_u *efile, 1753 char_u *errorformat, 1754 int newlist, // TRUE: start a new error list 1755 char_u *qf_title, 1756 char_u *enc) 1757 { 1758 qf_info_T *qi = &ql_info; 1759 1760 if (wp != NULL) 1761 { 1762 qi = ll_get_or_alloc_list(wp); 1763 if (qi == NULL) 1764 return FAIL; 1765 } 1766 1767 return qf_init_ext(qi, qi->qf_curlist, efile, curbuf, NULL, errorformat, 1768 newlist, (linenr_T)0, (linenr_T)0, qf_title, enc); 1769 } 1770 1771 /* 1772 * Set the title of the specified quickfix list. Frees the previous title. 1773 * Prepends ':' to the title. 1774 */ 1775 static void 1776 qf_store_title(qf_list_T *qfl, char_u *title) 1777 { 1778 VIM_CLEAR(qfl->qf_title); 1779 1780 if (title != NULL) 1781 { 1782 char_u *p = alloc((int)STRLEN(title) + 2); 1783 1784 qfl->qf_title = p; 1785 if (p != NULL) 1786 STRCPY(p, title); 1787 } 1788 } 1789 1790 /* 1791 * The title of a quickfix/location list is set, by default, to the command 1792 * that created the quickfix list with the ":" prefix. 1793 * Create a quickfix list title string by prepending ":" to a user command. 1794 * Returns a pointer to a static buffer with the title. 1795 */ 1796 static char_u * 1797 qf_cmdtitle(char_u *cmd) 1798 { 1799 static char_u qftitle_str[IOSIZE]; 1800 1801 vim_snprintf((char *)qftitle_str, IOSIZE, ":%s", (char *)cmd); 1802 return qftitle_str; 1803 } 1804 1805 /* 1806 * Prepare for adding a new quickfix list. If the current list is in the 1807 * middle of the stack, then all the following lists are freed and then 1808 * the new list is added. 1809 */ 1810 static void 1811 qf_new_list(qf_info_T *qi, char_u *qf_title) 1812 { 1813 int i; 1814 qf_list_T *qfl; 1815 1816 // If the current entry is not the last entry, delete entries beyond 1817 // the current entry. This makes it possible to browse in a tree-like 1818 // way with ":grep'. 1819 while (qi->qf_listcount > qi->qf_curlist + 1) 1820 qf_free(&qi->qf_lists[--qi->qf_listcount]); 1821 1822 // When the stack is full, remove to oldest entry 1823 // Otherwise, add a new entry. 1824 if (qi->qf_listcount == LISTCOUNT) 1825 { 1826 qf_free(&qi->qf_lists[0]); 1827 for (i = 1; i < LISTCOUNT; ++i) 1828 qi->qf_lists[i - 1] = qi->qf_lists[i]; 1829 qi->qf_curlist = LISTCOUNT - 1; 1830 } 1831 else 1832 qi->qf_curlist = qi->qf_listcount++; 1833 qfl = &qi->qf_lists[qi->qf_curlist]; 1834 vim_memset(qfl, 0, (size_t)(sizeof(qf_list_T))); 1835 qf_store_title(qfl, qf_title); 1836 qfl->qfl_type = qi->qfl_type; 1837 qfl->qf_id = ++last_qf_id; 1838 } 1839 1840 /* 1841 * Queue location list stack delete request. 1842 */ 1843 static void 1844 locstack_queue_delreq(qf_info_T *qi) 1845 { 1846 qf_delq_T *q; 1847 1848 q = (qf_delq_T *)alloc((unsigned)sizeof(qf_delq_T)); 1849 if (q != NULL) 1850 { 1851 q->qi = qi; 1852 q->next = qf_delq_head; 1853 qf_delq_head = q; 1854 } 1855 } 1856 1857 /* 1858 * Return the global quickfix stack window buffer number. 1859 */ 1860 int 1861 qf_stack_get_bufnr(void) 1862 { 1863 return ql_info.qf_bufnr; 1864 } 1865 1866 /* 1867 * Wipe the quickfix window buffer (if present) for the specified 1868 * quickfix/location list. 1869 */ 1870 static void 1871 wipe_qf_buffer(qf_info_T *qi) 1872 { 1873 buf_T *qfbuf; 1874 1875 if (qi->qf_bufnr != INVALID_QFBUFNR) 1876 { 1877 qfbuf = buflist_findnr(qi->qf_bufnr); 1878 if (qfbuf != NULL && qfbuf->b_nwindows == 0) 1879 { 1880 // If the quickfix buffer is not loaded in any window, then 1881 // wipe the buffer. 1882 close_buffer(NULL, qfbuf, DOBUF_WIPE, FALSE); 1883 qi->qf_bufnr = INVALID_QFBUFNR; 1884 } 1885 } 1886 } 1887 1888 /* 1889 * Free a location list stack 1890 */ 1891 static void 1892 ll_free_all(qf_info_T **pqi) 1893 { 1894 int i; 1895 qf_info_T *qi; 1896 1897 qi = *pqi; 1898 if (qi == NULL) 1899 return; 1900 *pqi = NULL; // Remove reference to this list 1901 1902 // If the location list is still in use, then queue the delete request 1903 // to be processed later. 1904 if (quickfix_busy > 0) 1905 { 1906 locstack_queue_delreq(qi); 1907 return; 1908 } 1909 1910 qi->qf_refcount--; 1911 if (qi->qf_refcount < 1) 1912 { 1913 // No references to this location list. 1914 // If the quickfix window buffer is loaded, then wipe it 1915 wipe_qf_buffer(qi); 1916 1917 for (i = 0; i < qi->qf_listcount; ++i) 1918 qf_free(&qi->qf_lists[i]); 1919 vim_free(qi); 1920 } 1921 } 1922 1923 /* 1924 * Free all the quickfix/location lists in the stack. 1925 */ 1926 void 1927 qf_free_all(win_T *wp) 1928 { 1929 int i; 1930 qf_info_T *qi = &ql_info; 1931 1932 if (wp != NULL) 1933 { 1934 // location list 1935 ll_free_all(&wp->w_llist); 1936 ll_free_all(&wp->w_llist_ref); 1937 } 1938 else 1939 // quickfix list 1940 for (i = 0; i < qi->qf_listcount; ++i) 1941 qf_free(&qi->qf_lists[i]); 1942 } 1943 1944 /* 1945 * Delay freeing of location list stacks when the quickfix code is running. 1946 * Used to avoid problems with autocmds freeing location list stacks when the 1947 * quickfix code is still referencing the stack. 1948 * Must always call decr_quickfix_busy() exactly once after this. 1949 */ 1950 static void 1951 incr_quickfix_busy(void) 1952 { 1953 quickfix_busy++; 1954 } 1955 1956 /* 1957 * Safe to free location list stacks. Process any delayed delete requests. 1958 */ 1959 static void 1960 decr_quickfix_busy(void) 1961 { 1962 if (--quickfix_busy == 0) 1963 { 1964 // No longer referencing the location lists. Process all the pending 1965 // delete requests. 1966 while (qf_delq_head != NULL) 1967 { 1968 qf_delq_T *q = qf_delq_head; 1969 1970 qf_delq_head = q->next; 1971 ll_free_all(&q->qi); 1972 vim_free(q); 1973 } 1974 } 1975 #ifdef ABORT_ON_INTERNAL_ERROR 1976 if (quickfix_busy < 0) 1977 { 1978 emsg("quickfix_busy has become negative"); 1979 abort(); 1980 } 1981 #endif 1982 } 1983 1984 #if defined(EXITFREE) || defined(PROTO) 1985 void 1986 check_quickfix_busy(void) 1987 { 1988 if (quickfix_busy != 0) 1989 { 1990 semsg("quickfix_busy not zero on exit: %ld", (long)quickfix_busy); 1991 # ifdef ABORT_ON_INTERNAL_ERROR 1992 abort(); 1993 # endif 1994 } 1995 } 1996 #endif 1997 1998 /* 1999 * Add an entry to the end of the list of errors. 2000 * Returns OK or FAIL. 2001 */ 2002 static int 2003 qf_add_entry( 2004 qf_info_T *qi, // quickfix list 2005 int qf_idx, // list index 2006 char_u *dir, // optional directory name 2007 char_u *fname, // file name or NULL 2008 char_u *module, // module name or NULL 2009 int bufnum, // buffer number or zero 2010 char_u *mesg, // message 2011 long lnum, // line number 2012 int col, // column 2013 int vis_col, // using visual column 2014 char_u *pattern, // search pattern 2015 int nr, // error number 2016 int type, // type character 2017 int valid) // valid entry 2018 { 2019 qf_list_T *qfl = &qi->qf_lists[qf_idx]; 2020 qfline_T *qfp; 2021 qfline_T **lastp; // pointer to qf_last or NULL 2022 2023 if ((qfp = (qfline_T *)alloc((unsigned)sizeof(qfline_T))) == NULL) 2024 return FAIL; 2025 if (bufnum != 0) 2026 { 2027 buf_T *buf = buflist_findnr(bufnum); 2028 2029 qfp->qf_fnum = bufnum; 2030 if (buf != NULL) 2031 buf->b_has_qf_entry |= 2032 IS_QF_LIST(qfl) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; 2033 } 2034 else 2035 qfp->qf_fnum = qf_get_fnum(qi, qf_idx, dir, fname); 2036 if ((qfp->qf_text = vim_strsave(mesg)) == NULL) 2037 { 2038 vim_free(qfp); 2039 return FAIL; 2040 } 2041 qfp->qf_lnum = lnum; 2042 qfp->qf_col = col; 2043 qfp->qf_viscol = vis_col; 2044 if (pattern == NULL || *pattern == NUL) 2045 qfp->qf_pattern = NULL; 2046 else if ((qfp->qf_pattern = vim_strsave(pattern)) == NULL) 2047 { 2048 vim_free(qfp->qf_text); 2049 vim_free(qfp); 2050 return FAIL; 2051 } 2052 if (module == NULL || *module == NUL) 2053 qfp->qf_module = NULL; 2054 else if ((qfp->qf_module = vim_strsave(module)) == NULL) 2055 { 2056 vim_free(qfp->qf_text); 2057 vim_free(qfp->qf_pattern); 2058 vim_free(qfp); 2059 return FAIL; 2060 } 2061 qfp->qf_nr = nr; 2062 if (type != 1 && !vim_isprintc(type)) // only printable chars allowed 2063 type = 0; 2064 qfp->qf_type = type; 2065 qfp->qf_valid = valid; 2066 2067 lastp = &qfl->qf_last; 2068 if (qf_list_empty(qi, qf_idx)) // first element in the list 2069 { 2070 qfl->qf_start = qfp; 2071 qfl->qf_ptr = qfp; 2072 qfl->qf_index = 0; 2073 qfp->qf_prev = NULL; 2074 } 2075 else 2076 { 2077 qfp->qf_prev = *lastp; 2078 (*lastp)->qf_next = qfp; 2079 } 2080 qfp->qf_next = NULL; 2081 qfp->qf_cleared = FALSE; 2082 *lastp = qfp; 2083 ++qfl->qf_count; 2084 if (qfl->qf_index == 0 && qfp->qf_valid) // first valid entry 2085 { 2086 qfl->qf_index = qfl->qf_count; 2087 qfl->qf_ptr = qfp; 2088 } 2089 2090 return OK; 2091 } 2092 2093 /* 2094 * Allocate a new quickfix/location list stack 2095 */ 2096 static qf_info_T * 2097 qf_alloc_stack(qfltype_T qfltype) 2098 { 2099 qf_info_T *qi; 2100 2101 qi = (qf_info_T *)alloc_clear((unsigned)sizeof(qf_info_T)); 2102 if (qi != NULL) 2103 { 2104 qi->qf_refcount++; 2105 qi->qfl_type = qfltype; 2106 qi->qf_bufnr = INVALID_QFBUFNR; 2107 } 2108 return qi; 2109 } 2110 2111 /* 2112 * Return the location list stack for window 'wp'. 2113 * If not present, allocate a location list stack 2114 */ 2115 static qf_info_T * 2116 ll_get_or_alloc_list(win_T *wp) 2117 { 2118 if (IS_LL_WINDOW(wp)) 2119 // For a location list window, use the referenced location list 2120 return wp->w_llist_ref; 2121 2122 // For a non-location list window, w_llist_ref should not point to a 2123 // location list. 2124 ll_free_all(&wp->w_llist_ref); 2125 2126 if (wp->w_llist == NULL) 2127 wp->w_llist = qf_alloc_stack(QFLT_LOCATION); // new location list 2128 return wp->w_llist; 2129 } 2130 2131 /* 2132 * Copy location list entries from 'from_qfl' to 'to_qfl'. 2133 */ 2134 static int 2135 copy_loclist_entries(qf_list_T *from_qfl, qf_list_T *to_qfl, qf_info_T *to_qi) 2136 { 2137 int i; 2138 qfline_T *from_qfp; 2139 qfline_T *prevp; 2140 2141 // copy all the location entries in this list 2142 for (i = 0, from_qfp = from_qfl->qf_start; 2143 i < from_qfl->qf_count && from_qfp != NULL; 2144 ++i, from_qfp = from_qfp->qf_next) 2145 { 2146 if (qf_add_entry(to_qi, 2147 to_qi->qf_curlist, 2148 NULL, 2149 NULL, 2150 from_qfp->qf_module, 2151 0, 2152 from_qfp->qf_text, 2153 from_qfp->qf_lnum, 2154 from_qfp->qf_col, 2155 from_qfp->qf_viscol, 2156 from_qfp->qf_pattern, 2157 from_qfp->qf_nr, 2158 0, 2159 from_qfp->qf_valid) == FAIL) 2160 return FAIL; 2161 2162 // qf_add_entry() will not set the qf_num field, as the 2163 // directory and file names are not supplied. So the qf_fnum 2164 // field is copied here. 2165 prevp = to_qfl->qf_last; 2166 prevp->qf_fnum = from_qfp->qf_fnum; // file number 2167 prevp->qf_type = from_qfp->qf_type; // error type 2168 if (from_qfl->qf_ptr == from_qfp) 2169 to_qfl->qf_ptr = prevp; // current location 2170 } 2171 2172 return OK; 2173 } 2174 2175 /* 2176 * Copy the specified location list 'from_qfl' to 'to_qfl'. 2177 */ 2178 static int 2179 copy_loclist(qf_list_T *from_qfl, qf_list_T *to_qfl, qf_info_T *to_qi) 2180 { 2181 // Some of the fields are populated by qf_add_entry() 2182 to_qfl->qfl_type = from_qfl->qfl_type; 2183 to_qfl->qf_nonevalid = from_qfl->qf_nonevalid; 2184 to_qfl->qf_count = 0; 2185 to_qfl->qf_index = 0; 2186 to_qfl->qf_start = NULL; 2187 to_qfl->qf_last = NULL; 2188 to_qfl->qf_ptr = NULL; 2189 if (from_qfl->qf_title != NULL) 2190 to_qfl->qf_title = vim_strsave(from_qfl->qf_title); 2191 else 2192 to_qfl->qf_title = NULL; 2193 if (from_qfl->qf_ctx != NULL) 2194 { 2195 to_qfl->qf_ctx = alloc_tv(); 2196 if (to_qfl->qf_ctx != NULL) 2197 copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx); 2198 } 2199 else 2200 to_qfl->qf_ctx = NULL; 2201 2202 if (from_qfl->qf_count) 2203 if (copy_loclist_entries(from_qfl, to_qfl, to_qi) == FAIL) 2204 return FAIL; 2205 2206 to_qfl->qf_index = from_qfl->qf_index; // current index in the list 2207 2208 // Assign a new ID for the location list 2209 to_qfl->qf_id = ++last_qf_id; 2210 to_qfl->qf_changedtick = 0L; 2211 2212 // When no valid entries are present in the list, qf_ptr points to 2213 // the first item in the list 2214 if (to_qfl->qf_nonevalid) 2215 { 2216 to_qfl->qf_ptr = to_qfl->qf_start; 2217 to_qfl->qf_index = 1; 2218 } 2219 2220 return OK; 2221 } 2222 2223 /* 2224 * Copy the location list stack 'from' window to 'to' window. 2225 */ 2226 void 2227 copy_loclist_stack(win_T *from, win_T *to) 2228 { 2229 qf_info_T *qi; 2230 int idx; 2231 2232 // When copying from a location list window, copy the referenced 2233 // location list. For other windows, copy the location list for 2234 // that window. 2235 if (IS_LL_WINDOW(from)) 2236 qi = from->w_llist_ref; 2237 else 2238 qi = from->w_llist; 2239 2240 if (qi == NULL) // no location list to copy 2241 return; 2242 2243 // allocate a new location list 2244 if ((to->w_llist = qf_alloc_stack(QFLT_LOCATION)) == NULL) 2245 return; 2246 2247 to->w_llist->qf_listcount = qi->qf_listcount; 2248 2249 // Copy the location lists one at a time 2250 for (idx = 0; idx < qi->qf_listcount; ++idx) 2251 { 2252 to->w_llist->qf_curlist = idx; 2253 2254 if (copy_loclist(&qi->qf_lists[idx], 2255 &to->w_llist->qf_lists[idx], to->w_llist) == FAIL) 2256 { 2257 qf_free_all(to); 2258 return; 2259 } 2260 } 2261 2262 to->w_llist->qf_curlist = qi->qf_curlist; // current list 2263 } 2264 2265 /* 2266 * Get buffer number for file "directory/fname". 2267 * Also sets the b_has_qf_entry flag. 2268 */ 2269 static int 2270 qf_get_fnum(qf_info_T *qi, int qf_idx, char_u *directory, char_u *fname) 2271 { 2272 qf_list_T *qfl = &qi->qf_lists[qf_idx]; 2273 char_u *ptr = NULL; 2274 buf_T *buf; 2275 char_u *bufname; 2276 2277 if (fname == NULL || *fname == NUL) // no file name 2278 return 0; 2279 2280 #ifdef VMS 2281 vms_remove_version(fname); 2282 #endif 2283 #ifdef BACKSLASH_IN_FILENAME 2284 if (directory != NULL) 2285 slash_adjust(directory); 2286 slash_adjust(fname); 2287 #endif 2288 if (directory != NULL && !vim_isAbsName(fname) 2289 && (ptr = concat_fnames(directory, fname, TRUE)) != NULL) 2290 { 2291 // Here we check if the file really exists. 2292 // This should normally be true, but if make works without 2293 // "leaving directory"-messages we might have missed a 2294 // directory change. 2295 if (mch_getperm(ptr) < 0) 2296 { 2297 vim_free(ptr); 2298 directory = qf_guess_filepath(qfl, fname); 2299 if (directory) 2300 ptr = concat_fnames(directory, fname, TRUE); 2301 else 2302 ptr = vim_strsave(fname); 2303 } 2304 // Use concatenated directory name and file name 2305 bufname = ptr; 2306 } 2307 else 2308 bufname = fname; 2309 2310 if (qf_last_bufname != NULL && STRCMP(bufname, qf_last_bufname) == 0 2311 && bufref_valid(&qf_last_bufref)) 2312 { 2313 buf = qf_last_bufref.br_buf; 2314 vim_free(ptr); 2315 } 2316 else 2317 { 2318 vim_free(qf_last_bufname); 2319 buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT); 2320 if (bufname == ptr) 2321 qf_last_bufname = bufname; 2322 else 2323 qf_last_bufname = vim_strsave(bufname); 2324 set_bufref(&qf_last_bufref, buf); 2325 } 2326 if (buf == NULL) 2327 return 0; 2328 2329 buf->b_has_qf_entry = 2330 IS_QF_LIST(qfl) ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; 2331 return buf->b_fnum; 2332 } 2333 2334 /* 2335 * Push dirbuf onto the directory stack and return pointer to actual dir or 2336 * NULL on error. 2337 */ 2338 static char_u * 2339 qf_push_dir(char_u *dirbuf, struct dir_stack_T **stackptr, int is_file_stack) 2340 { 2341 struct dir_stack_T *ds_new; 2342 struct dir_stack_T *ds_ptr; 2343 2344 // allocate new stack element and hook it in 2345 ds_new = (struct dir_stack_T *)alloc((unsigned)sizeof(struct dir_stack_T)); 2346 if (ds_new == NULL) 2347 return NULL; 2348 2349 ds_new->next = *stackptr; 2350 *stackptr = ds_new; 2351 2352 // store directory on the stack 2353 if (vim_isAbsName(dirbuf) 2354 || (*stackptr)->next == NULL 2355 || (*stackptr && is_file_stack)) 2356 (*stackptr)->dirname = vim_strsave(dirbuf); 2357 else 2358 { 2359 // Okay we don't have an absolute path. 2360 // dirbuf must be a subdir of one of the directories on the stack. 2361 // Let's search... 2362 ds_new = (*stackptr)->next; 2363 (*stackptr)->dirname = NULL; 2364 while (ds_new) 2365 { 2366 vim_free((*stackptr)->dirname); 2367 (*stackptr)->dirname = concat_fnames(ds_new->dirname, dirbuf, 2368 TRUE); 2369 if (mch_isdir((*stackptr)->dirname) == TRUE) 2370 break; 2371 2372 ds_new = ds_new->next; 2373 } 2374 2375 // clean up all dirs we already left 2376 while ((*stackptr)->next != ds_new) 2377 { 2378 ds_ptr = (*stackptr)->next; 2379 (*stackptr)->next = (*stackptr)->next->next; 2380 vim_free(ds_ptr->dirname); 2381 vim_free(ds_ptr); 2382 } 2383 2384 // Nothing found -> it must be on top level 2385 if (ds_new == NULL) 2386 { 2387 vim_free((*stackptr)->dirname); 2388 (*stackptr)->dirname = vim_strsave(dirbuf); 2389 } 2390 } 2391 2392 if ((*stackptr)->dirname != NULL) 2393 return (*stackptr)->dirname; 2394 else 2395 { 2396 ds_ptr = *stackptr; 2397 *stackptr = (*stackptr)->next; 2398 vim_free(ds_ptr); 2399 return NULL; 2400 } 2401 } 2402 2403 /* 2404 * pop dirbuf from the directory stack and return previous directory or NULL if 2405 * stack is empty 2406 */ 2407 static char_u * 2408 qf_pop_dir(struct dir_stack_T **stackptr) 2409 { 2410 struct dir_stack_T *ds_ptr; 2411 2412 // TODO: Should we check if dirbuf is the directory on top of the stack? 2413 // What to do if it isn't? 2414 2415 // pop top element and free it 2416 if (*stackptr != NULL) 2417 { 2418 ds_ptr = *stackptr; 2419 *stackptr = (*stackptr)->next; 2420 vim_free(ds_ptr->dirname); 2421 vim_free(ds_ptr); 2422 } 2423 2424 // return NEW top element as current dir or NULL if stack is empty 2425 return *stackptr ? (*stackptr)->dirname : NULL; 2426 } 2427 2428 /* 2429 * clean up directory stack 2430 */ 2431 static void 2432 qf_clean_dir_stack(struct dir_stack_T **stackptr) 2433 { 2434 struct dir_stack_T *ds_ptr; 2435 2436 while ((ds_ptr = *stackptr) != NULL) 2437 { 2438 *stackptr = (*stackptr)->next; 2439 vim_free(ds_ptr->dirname); 2440 vim_free(ds_ptr); 2441 } 2442 } 2443 2444 /* 2445 * Check in which directory of the directory stack the given file can be 2446 * found. 2447 * Returns a pointer to the directory name or NULL if not found. 2448 * Cleans up intermediate directory entries. 2449 * 2450 * TODO: How to solve the following problem? 2451 * If we have this directory tree: 2452 * ./ 2453 * ./aa 2454 * ./aa/bb 2455 * ./bb 2456 * ./bb/x.c 2457 * and make says: 2458 * making all in aa 2459 * making all in bb 2460 * x.c:9: Error 2461 * Then qf_push_dir thinks we are in ./aa/bb, but we are in ./bb. 2462 * qf_guess_filepath will return NULL. 2463 */ 2464 static char_u * 2465 qf_guess_filepath(qf_list_T *qfl, char_u *filename) 2466 { 2467 struct dir_stack_T *ds_ptr; 2468 struct dir_stack_T *ds_tmp; 2469 char_u *fullname; 2470 2471 // no dirs on the stack - there's nothing we can do 2472 if (qfl->qf_dir_stack == NULL) 2473 return NULL; 2474 2475 ds_ptr = qfl->qf_dir_stack->next; 2476 fullname = NULL; 2477 while (ds_ptr) 2478 { 2479 vim_free(fullname); 2480 fullname = concat_fnames(ds_ptr->dirname, filename, TRUE); 2481 2482 // If concat_fnames failed, just go on. The worst thing that can happen 2483 // is that we delete the entire stack. 2484 if ((fullname != NULL) && (mch_getperm(fullname) >= 0)) 2485 break; 2486 2487 ds_ptr = ds_ptr->next; 2488 } 2489 2490 vim_free(fullname); 2491 2492 // clean up all dirs we already left 2493 while (qfl->qf_dir_stack->next != ds_ptr) 2494 { 2495 ds_tmp = qfl->qf_dir_stack->next; 2496 qfl->qf_dir_stack->next = qfl->qf_dir_stack->next->next; 2497 vim_free(ds_tmp->dirname); 2498 vim_free(ds_tmp); 2499 } 2500 2501 return ds_ptr == NULL ? NULL : ds_ptr->dirname; 2502 } 2503 2504 /* 2505 * Returns TRUE if a quickfix/location list with the given identifier exists. 2506 */ 2507 static int 2508 qflist_valid(win_T *wp, int_u qf_id) 2509 { 2510 qf_info_T *qi = &ql_info; 2511 int i; 2512 2513 if (wp != NULL) 2514 { 2515 qi = GET_LOC_LIST(wp); // Location list 2516 if (qi == NULL) 2517 return FALSE; 2518 } 2519 2520 for (i = 0; i < qi->qf_listcount; ++i) 2521 if (qi->qf_lists[i].qf_id == qf_id) 2522 return TRUE; 2523 2524 return FALSE; 2525 } 2526 2527 /* 2528 * When loading a file from the quickfix, the autocommands may modify it. 2529 * This may invalidate the current quickfix entry. This function checks 2530 * whether an entry is still present in the quickfix list. 2531 * Similar to location list. 2532 */ 2533 static int 2534 is_qf_entry_present(qf_list_T *qfl, qfline_T *qf_ptr) 2535 { 2536 qfline_T *qfp; 2537 int i; 2538 2539 // Search for the entry in the current list 2540 for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count; 2541 ++i, qfp = qfp->qf_next) 2542 if (qfp == NULL || qfp == qf_ptr) 2543 break; 2544 2545 if (i == qfl->qf_count) // Entry is not found 2546 return FALSE; 2547 2548 return TRUE; 2549 } 2550 2551 /* 2552 * Get the next valid entry in the current quickfix/location list. The search 2553 * starts from the current entry. Returns NULL on failure. 2554 */ 2555 static qfline_T * 2556 get_next_valid_entry( 2557 qf_list_T *qfl, 2558 qfline_T *qf_ptr, 2559 int *qf_index, 2560 int dir) 2561 { 2562 int idx; 2563 int old_qf_fnum; 2564 2565 idx = *qf_index; 2566 old_qf_fnum = qf_ptr->qf_fnum; 2567 2568 do 2569 { 2570 if (idx == qfl->qf_count || qf_ptr->qf_next == NULL) 2571 return NULL; 2572 ++idx; 2573 qf_ptr = qf_ptr->qf_next; 2574 } while ((!qfl->qf_nonevalid && !qf_ptr->qf_valid) 2575 || (dir == FORWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum)); 2576 2577 *qf_index = idx; 2578 return qf_ptr; 2579 } 2580 2581 /* 2582 * Get the previous valid entry in the current quickfix/location list. The 2583 * search starts from the current entry. Returns NULL on failure. 2584 */ 2585 static qfline_T * 2586 get_prev_valid_entry( 2587 qf_list_T *qfl, 2588 qfline_T *qf_ptr, 2589 int *qf_index, 2590 int dir) 2591 { 2592 int idx; 2593 int old_qf_fnum; 2594 2595 idx = *qf_index; 2596 old_qf_fnum = qf_ptr->qf_fnum; 2597 2598 do 2599 { 2600 if (idx == 1 || qf_ptr->qf_prev == NULL) 2601 return NULL; 2602 --idx; 2603 qf_ptr = qf_ptr->qf_prev; 2604 } while ((!qfl->qf_nonevalid && !qf_ptr->qf_valid) 2605 || (dir == BACKWARD_FILE && qf_ptr->qf_fnum == old_qf_fnum)); 2606 2607 *qf_index = idx; 2608 return qf_ptr; 2609 } 2610 2611 /* 2612 * Get the n'th (errornr) previous/next valid entry from the current entry in 2613 * the quickfix list. 2614 * dir == FORWARD or FORWARD_FILE: next valid entry 2615 * dir == BACKWARD or BACKWARD_FILE: previous valid entry 2616 */ 2617 static qfline_T * 2618 get_nth_valid_entry( 2619 qf_list_T *qfl, 2620 int errornr, 2621 int dir, 2622 int *new_qfidx) 2623 { 2624 qfline_T *qf_ptr = qfl->qf_ptr; 2625 int qf_idx = qfl->qf_index; 2626 qfline_T *prev_qf_ptr; 2627 int prev_index; 2628 static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); 2629 char_u *err = e_no_more_items; 2630 2631 while (errornr--) 2632 { 2633 prev_qf_ptr = qf_ptr; 2634 prev_index = qf_idx; 2635 2636 if (dir == FORWARD || dir == FORWARD_FILE) 2637 qf_ptr = get_next_valid_entry(qfl, qf_ptr, &qf_idx, dir); 2638 else 2639 qf_ptr = get_prev_valid_entry(qfl, qf_ptr, &qf_idx, dir); 2640 if (qf_ptr == NULL) 2641 { 2642 qf_ptr = prev_qf_ptr; 2643 qf_idx = prev_index; 2644 if (err != NULL) 2645 { 2646 emsg(_(err)); 2647 return NULL; 2648 } 2649 break; 2650 } 2651 2652 err = NULL; 2653 } 2654 2655 *new_qfidx = qf_idx; 2656 return qf_ptr; 2657 } 2658 2659 /* 2660 * Get n'th (errornr) quickfix entry from the current entry in the quickfix 2661 * list 'qfl'. Returns a pointer to the new entry and the index in 'new_qfidx' 2662 */ 2663 static qfline_T * 2664 get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx) 2665 { 2666 qfline_T *qf_ptr = qfl->qf_ptr; 2667 int qf_idx = qfl->qf_index; 2668 2669 // New error number is less than the current error number 2670 while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL) 2671 { 2672 --qf_idx; 2673 qf_ptr = qf_ptr->qf_prev; 2674 } 2675 // New error number is greater than the current error number 2676 while (errornr > qf_idx && qf_idx < qfl->qf_count && 2677 qf_ptr->qf_next != NULL) 2678 { 2679 ++qf_idx; 2680 qf_ptr = qf_ptr->qf_next; 2681 } 2682 2683 *new_qfidx = qf_idx; 2684 return qf_ptr; 2685 } 2686 2687 /* 2688 * Get a entry specied by 'errornr' and 'dir' from the current 2689 * quickfix/location list. 'errornr' specifies the index of the entry and 'dir' 2690 * specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE). 2691 * Returns a pointer to the entry and the index of the new entry is stored in 2692 * 'new_qfidx'. 2693 */ 2694 static qfline_T * 2695 qf_get_entry( 2696 qf_list_T *qfl, 2697 int errornr, 2698 int dir, 2699 int *new_qfidx) 2700 { 2701 qfline_T *qf_ptr = qfl->qf_ptr; 2702 int qfidx = qfl->qf_index; 2703 2704 if (dir != 0) // next/prev valid entry 2705 qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx); 2706 else if (errornr != 0) // go to specified number 2707 qf_ptr = get_nth_entry(qfl, errornr, &qfidx); 2708 2709 *new_qfidx = qfidx; 2710 return qf_ptr; 2711 } 2712 2713 /* 2714 * Find a window displaying a Vim help file. 2715 */ 2716 static win_T * 2717 qf_find_help_win(void) 2718 { 2719 win_T *wp; 2720 2721 FOR_ALL_WINDOWS(wp) 2722 if (bt_help(wp->w_buffer)) 2723 return wp; 2724 2725 return NULL; 2726 } 2727 2728 /* 2729 * Find a help window or open one. If 'newwin' is TRUE, then open a new help 2730 * window. 2731 */ 2732 static int 2733 jump_to_help_window(qf_info_T *qi, int newwin, int *opened_window) 2734 { 2735 win_T *wp; 2736 int flags; 2737 2738 if (cmdmod.tab != 0 || newwin) 2739 wp = NULL; 2740 else 2741 wp = qf_find_help_win(); 2742 if (wp != NULL && wp->w_buffer->b_nwindows > 0) 2743 win_enter(wp, TRUE); 2744 else 2745 { 2746 // Split off help window; put it at far top if no position 2747 // specified, the current window is vertically split and narrow. 2748 flags = WSP_HELP; 2749 if (cmdmod.split == 0 && curwin->w_width != Columns 2750 && curwin->w_width < 80) 2751 flags |= WSP_TOP; 2752 // If the user asks to open a new window, then copy the location list. 2753 // Otherwise, don't copy the location list. 2754 if (IS_LL_STACK(qi) && !newwin) 2755 flags |= WSP_NEWLOC; 2756 2757 if (win_split(0, flags) == FAIL) 2758 return FAIL; 2759 2760 *opened_window = TRUE; 2761 2762 if (curwin->w_height < p_hh) 2763 win_setheight((int)p_hh); 2764 2765 // When using location list, the new window should use the supplied 2766 // location list. If the user asks to open a new window, then the new 2767 // window will get a copy of the location list. 2768 if (IS_LL_STACK(qi) && !newwin) 2769 { 2770 curwin->w_llist = qi; 2771 qi->qf_refcount++; 2772 } 2773 } 2774 2775 if (!p_im) 2776 restart_edit = 0; // don't want insert mode in help file 2777 2778 return OK; 2779 } 2780 2781 /* 2782 * Find a non-quickfix window in the current tabpage using the given location 2783 * list stack. 2784 * Returns NULL if a matching window is not found. 2785 */ 2786 static win_T * 2787 qf_find_win_with_loclist(qf_info_T *ll) 2788 { 2789 win_T *wp; 2790 2791 FOR_ALL_WINDOWS(wp) 2792 if (wp->w_llist == ll && !bt_quickfix(wp->w_buffer)) 2793 return wp; 2794 2795 return NULL; 2796 } 2797 2798 /* 2799 * Find a window containing a normal buffer 2800 */ 2801 static win_T * 2802 qf_find_win_with_normal_buf(void) 2803 { 2804 win_T *wp; 2805 2806 FOR_ALL_WINDOWS(wp) 2807 if (bt_normal(wp->w_buffer)) 2808 return wp; 2809 2810 return NULL; 2811 } 2812 2813 /* 2814 * Go to a window in any tabpage containing the specified file. Returns TRUE 2815 * if successfully jumped to the window. Otherwise returns FALSE. 2816 */ 2817 static int 2818 qf_goto_tabwin_with_file(int fnum) 2819 { 2820 tabpage_T *tp; 2821 win_T *wp; 2822 2823 FOR_ALL_TAB_WINDOWS(tp, wp) 2824 if (wp->w_buffer->b_fnum == fnum) 2825 { 2826 goto_tabpage_win(tp, wp); 2827 return TRUE; 2828 } 2829 2830 return FALSE; 2831 } 2832 2833 /* 2834 * Create a new window to show a file above the quickfix window. Called when 2835 * only the quickfix window is present. 2836 */ 2837 static int 2838 qf_open_new_file_win(qf_info_T *ll_ref) 2839 { 2840 int flags; 2841 2842 flags = WSP_ABOVE; 2843 if (ll_ref != NULL) 2844 flags |= WSP_NEWLOC; 2845 if (win_split(0, flags) == FAIL) 2846 return FAIL; // not enough room for window 2847 p_swb = empty_option; // don't split again 2848 swb_flags = 0; 2849 RESET_BINDING(curwin); 2850 if (ll_ref != NULL) 2851 { 2852 // The new window should use the location list from the 2853 // location list window 2854 curwin->w_llist = ll_ref; 2855 ll_ref->qf_refcount++; 2856 } 2857 return OK; 2858 } 2859 2860 /* 2861 * Go to a window that shows the right buffer. If the window is not found, go 2862 * to the window just above the location list window. This is used for opening 2863 * a file from a location window and not from a quickfix window. If some usable 2864 * window is previously found, then it is supplied in 'use_win'. 2865 */ 2866 static void 2867 qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref) 2868 { 2869 win_T *win = use_win; 2870 2871 if (win == NULL) 2872 { 2873 // Find the window showing the selected file 2874 FOR_ALL_WINDOWS(win) 2875 if (win->w_buffer->b_fnum == qf_fnum) 2876 break; 2877 if (win == NULL) 2878 { 2879 // Find a previous usable window 2880 win = curwin; 2881 do 2882 { 2883 if (bt_normal(win->w_buffer)) 2884 break; 2885 if (win->w_prev == NULL) 2886 win = lastwin; // wrap around the top 2887 else 2888 win = win->w_prev; // go to previous window 2889 } while (win != curwin); 2890 } 2891 } 2892 win_goto(win); 2893 2894 // If the location list for the window is not set, then set it 2895 // to the location list from the location window 2896 if (win->w_llist == NULL) 2897 { 2898 win->w_llist = ll_ref; 2899 if (ll_ref != NULL) 2900 ll_ref->qf_refcount++; 2901 } 2902 } 2903 2904 /* 2905 * Go to a window that contains the specified buffer 'qf_fnum'. If a window is 2906 * not found, then go to the window just above the quickfix window. This is 2907 * used for opening a file from a quickfix window and not from a location 2908 * window. 2909 */ 2910 static void 2911 qf_goto_win_with_qfl_file(int qf_fnum) 2912 { 2913 win_T *win; 2914 win_T *altwin; 2915 2916 win = curwin; 2917 altwin = NULL; 2918 for (;;) 2919 { 2920 if (win->w_buffer->b_fnum == qf_fnum) 2921 break; 2922 if (win->w_prev == NULL) 2923 win = lastwin; // wrap around the top 2924 else 2925 win = win->w_prev; // go to previous window 2926 2927 if (IS_QF_WINDOW(win)) 2928 { 2929 // Didn't find it, go to the window before the quickfix 2930 // window. 2931 if (altwin != NULL) 2932 win = altwin; 2933 else if (curwin->w_prev != NULL) 2934 win = curwin->w_prev; 2935 else 2936 win = curwin->w_next; 2937 break; 2938 } 2939 2940 // Remember a usable window. 2941 if (altwin == NULL && !win->w_p_pvw && bt_normal(win->w_buffer)) 2942 altwin = win; 2943 } 2944 2945 win_goto(win); 2946 } 2947 2948 /* 2949 * Find a suitable window for opening a file (qf_fnum) from the 2950 * quickfix/location list and jump to it. If the file is already opened in a 2951 * window, jump to it. Otherwise open a new window to display the file. If 2952 * 'newwin' is TRUE, then always open a new window. This is called from either 2953 * a quickfix or a location list window. 2954 */ 2955 static int 2956 qf_jump_to_usable_window(int qf_fnum, int newwin, int *opened_window) 2957 { 2958 win_T *usable_win_ptr = NULL; 2959 int usable_win; 2960 qf_info_T *ll_ref = NULL; 2961 win_T *win; 2962 2963 usable_win = 0; 2964 2965 // If opening a new window, then don't use the location list referred by 2966 // the current window. Otherwise two windows will refer to the same 2967 // location list. 2968 if (!newwin) 2969 ll_ref = curwin->w_llist_ref; 2970 2971 if (ll_ref != NULL) 2972 { 2973 // Find a non-quickfix window with this location list 2974 usable_win_ptr = qf_find_win_with_loclist(ll_ref); 2975 if (usable_win_ptr != NULL) 2976 usable_win = 1; 2977 } 2978 2979 if (!usable_win) 2980 { 2981 // Locate a window showing a normal buffer 2982 win = qf_find_win_with_normal_buf(); 2983 if (win != NULL) 2984 usable_win = 1; 2985 } 2986 2987 // If no usable window is found and 'switchbuf' contains "usetab" 2988 // then search in other tabs. 2989 if (!usable_win && (swb_flags & SWB_USETAB)) 2990 usable_win = qf_goto_tabwin_with_file(qf_fnum); 2991 2992 // If there is only one window and it is the quickfix window, create a 2993 // new one above the quickfix window. 2994 if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win || newwin) 2995 { 2996 if (qf_open_new_file_win(ll_ref) != OK) 2997 return FAIL; 2998 *opened_window = TRUE; // close it when fail 2999 } 3000 else 3001 { 3002 if (curwin->w_llist_ref != NULL) // In a location window 3003 qf_goto_win_with_ll_file(usable_win_ptr, qf_fnum, ll_ref); 3004 else // In a quickfix window 3005 qf_goto_win_with_qfl_file(qf_fnum); 3006 } 3007 3008 return OK; 3009 } 3010 3011 /* 3012 * Edit the selected file or help file. 3013 * Returns OK if successfully edited the file, FAIL on failing to open the 3014 * buffer and NOTDONE if the quickfix/location list was freed by an autocmd 3015 * when opening the buffer. 3016 */ 3017 static int 3018 qf_jump_edit_buffer( 3019 qf_info_T *qi, 3020 qfline_T *qf_ptr, 3021 int forceit, 3022 int prev_winid, 3023 int *opened_window) 3024 { 3025 qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; 3026 qfltype_T qfl_type = qfl->qfl_type; 3027 int retval = OK; 3028 int old_qf_curlist = qi->qf_curlist; 3029 int save_qfid = qfl->qf_id; 3030 3031 if (qf_ptr->qf_type == 1) 3032 { 3033 // Open help file (do_ecmd() will set b_help flag, readfile() will 3034 // set b_p_ro flag). 3035 if (!can_abandon(curbuf, forceit)) 3036 { 3037 no_write_message(); 3038 return FAIL; 3039 } 3040 3041 retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1, 3042 ECMD_HIDE + ECMD_SET_HELP, 3043 prev_winid == curwin->w_id ? curwin : NULL); 3044 } 3045 else 3046 retval = buflist_getfile(qf_ptr->qf_fnum, 3047 (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit); 3048 3049 // If a location list, check whether the associated window is still 3050 // present. 3051 if (qfl_type == QFLT_LOCATION) 3052 { 3053 win_T *wp = win_id2wp(prev_winid); 3054 if (wp == NULL && curwin->w_llist != qi) 3055 { 3056 emsg(_("E924: Current window was closed")); 3057 *opened_window = FALSE; 3058 return NOTDONE; 3059 } 3060 } 3061 3062 if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid)) 3063 { 3064 emsg(_("E925: Current quickfix was changed")); 3065 return NOTDONE; 3066 } 3067 3068 if (old_qf_curlist != qi->qf_curlist 3069 || !is_qf_entry_present(qfl, qf_ptr)) 3070 { 3071 if (qfl_type == QFLT_QUICKFIX) 3072 emsg(_("E925: Current quickfix was changed")); 3073 else 3074 emsg(_(e_loc_list_changed)); 3075 return NOTDONE; 3076 } 3077 3078 return retval; 3079 } 3080 3081 /* 3082 * Go to the error line in the current file using either line/column number or 3083 * a search pattern. 3084 */ 3085 static void 3086 qf_jump_goto_line( 3087 linenr_T qf_lnum, 3088 int qf_col, 3089 char_u qf_viscol, 3090 char_u *qf_pattern) 3091 { 3092 linenr_T i; 3093 3094 if (qf_pattern == NULL) 3095 { 3096 // Go to line with error, unless qf_lnum is 0. 3097 i = qf_lnum; 3098 if (i > 0) 3099 { 3100 if (i > curbuf->b_ml.ml_line_count) 3101 i = curbuf->b_ml.ml_line_count; 3102 curwin->w_cursor.lnum = i; 3103 } 3104 if (qf_col > 0) 3105 { 3106 curwin->w_cursor.coladd = 0; 3107 if (qf_viscol == TRUE) 3108 coladvance(qf_col - 1); 3109 else 3110 curwin->w_cursor.col = qf_col - 1; 3111 curwin->w_set_curswant = TRUE; 3112 check_cursor(); 3113 } 3114 else 3115 beginline(BL_WHITE | BL_FIX); 3116 } 3117 else 3118 { 3119 pos_T save_cursor; 3120 3121 // Move the cursor to the first line in the buffer 3122 save_cursor = curwin->w_cursor; 3123 curwin->w_cursor.lnum = 0; 3124 if (!do_search(NULL, '/', qf_pattern, (long)1, 3125 SEARCH_KEEP, NULL, NULL)) 3126 curwin->w_cursor = save_cursor; 3127 } 3128 } 3129 3130 /* 3131 * Display quickfix list index and size message 3132 */ 3133 static void 3134 qf_jump_print_msg( 3135 qf_info_T *qi, 3136 int qf_index, 3137 qfline_T *qf_ptr, 3138 buf_T *old_curbuf, 3139 linenr_T old_lnum) 3140 { 3141 linenr_T i; 3142 int len; 3143 3144 // Update the screen before showing the message, unless the screen 3145 // scrolled up. 3146 if (!msg_scrolled) 3147 update_topline_redraw(); 3148 sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index, 3149 qi->qf_lists[qi->qf_curlist].qf_count, 3150 qf_ptr->qf_cleared ? _(" (line deleted)") : "", 3151 (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr)); 3152 // Add the message, skipping leading whitespace and newlines. 3153 len = (int)STRLEN(IObuff); 3154 qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len); 3155 3156 // Output the message. Overwrite to avoid scrolling when the 'O' 3157 // flag is present in 'shortmess'; But when not jumping, print the 3158 // whole message. 3159 i = msg_scroll; 3160 if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum) 3161 msg_scroll = TRUE; 3162 else if (!msg_scrolled && shortmess(SHM_OVERALL)) 3163 msg_scroll = FALSE; 3164 msg_attr_keep((char *)IObuff, 0, TRUE); 3165 msg_scroll = i; 3166 } 3167 3168 /* 3169 * Find a usable window for opening a file from the quickfix/location list. If 3170 * a window is not found then open a new window. If 'newwin' is TRUE, then open 3171 * a new window. 3172 * Returns OK if successfully jumped or opened a window. Returns FAIL if not 3173 * able to jump/open a window. Returns NOTDONE if a file is not associated 3174 * with the entry. 3175 */ 3176 static int 3177 qf_jump_open_window( 3178 qf_info_T *qi, 3179 qfline_T *qf_ptr, 3180 int newwin, 3181 int *opened_window) 3182 { 3183 // For ":helpgrep" find a help window or open one. 3184 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) 3185 if (jump_to_help_window(qi, newwin, opened_window) == FAIL) 3186 return FAIL; 3187 3188 // If currently in the quickfix window, find another window to show the 3189 // file in. 3190 if (bt_quickfix(curbuf) && !*opened_window) 3191 { 3192 // If there is no file specified, we don't know where to go. 3193 // But do advance, otherwise ":cn" gets stuck. 3194 if (qf_ptr->qf_fnum == 0) 3195 return NOTDONE; 3196 3197 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, newwin, 3198 opened_window) == FAIL) 3199 return FAIL; 3200 } 3201 3202 return OK; 3203 } 3204 3205 /* 3206 * Edit a selected file from the quickfix/location list and jump to a 3207 * particular line/column, adjust the folds and display a message about the 3208 * jump. 3209 * Returns OK on success and FAIL on failing to open the file/buffer. Returns 3210 * NOTDONE if the quickfix/location list is freed by an autocmd when opening 3211 * the file. 3212 */ 3213 static int 3214 qf_jump_to_buffer( 3215 qf_info_T *qi, 3216 int qf_index, 3217 qfline_T *qf_ptr, 3218 int forceit, 3219 int prev_winid, 3220 int *opened_window, 3221 int openfold, 3222 int print_message) 3223 { 3224 buf_T *old_curbuf; 3225 linenr_T old_lnum; 3226 int retval = OK; 3227 3228 // If there is a file name, read the wanted file if needed, and check 3229 // autowrite etc. 3230 old_curbuf = curbuf; 3231 old_lnum = curwin->w_cursor.lnum; 3232 3233 if (qf_ptr->qf_fnum != 0) 3234 { 3235 retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, prev_winid, 3236 opened_window); 3237 if (retval != OK) 3238 return retval; 3239 } 3240 3241 // When not switched to another buffer, still need to set pc mark 3242 if (curbuf == old_curbuf) 3243 setpcmark(); 3244 3245 qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol, 3246 qf_ptr->qf_pattern); 3247 3248 #ifdef FEAT_FOLDING 3249 if ((fdo_flags & FDO_QUICKFIX) && openfold) 3250 foldOpenCursor(); 3251 #endif 3252 if (print_message) 3253 qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum); 3254 3255 return retval; 3256 } 3257 3258 /* 3259 * Jump to a quickfix line and try to use an existing window. 3260 */ 3261 void 3262 qf_jump(qf_info_T *qi, 3263 int dir, 3264 int errornr, 3265 int forceit) 3266 { 3267 qf_jump_newwin(qi, dir, errornr, forceit, FALSE); 3268 } 3269 3270 /* 3271 * Jump to a quickfix line. 3272 * If dir == 0 go to entry "errornr". 3273 * If dir == FORWARD go "errornr" valid entries forward. 3274 * If dir == BACKWARD go "errornr" valid entries backward. 3275 * If dir == FORWARD_FILE go "errornr" valid entries files backward. 3276 * If dir == BACKWARD_FILE go "errornr" valid entries files backward 3277 * else if "errornr" is zero, redisplay the same line 3278 * If 'forceit' is TRUE, then can discard changes to the current buffer. 3279 * If 'newwin' is TRUE, then open the file in a new window. 3280 */ 3281 void 3282 qf_jump_newwin(qf_info_T *qi, 3283 int dir, 3284 int errornr, 3285 int forceit, 3286 int newwin) 3287 { 3288 qf_list_T *qfl; 3289 qfline_T *qf_ptr; 3290 qfline_T *old_qf_ptr; 3291 int qf_index; 3292 int old_qf_index; 3293 char_u *old_swb = p_swb; 3294 unsigned old_swb_flags = swb_flags; 3295 int prev_winid; 3296 int opened_window = FALSE; 3297 int print_message = TRUE; 3298 #ifdef FEAT_FOLDING 3299 int old_KeyTyped = KeyTyped; // getting file may reset it 3300 #endif 3301 int retval = OK; 3302 3303 if (qi == NULL) 3304 qi = &ql_info; 3305 3306 if (qf_stack_empty(qi) || qf_list_empty(qi, qi->qf_curlist)) 3307 { 3308 emsg(_(e_quickfix)); 3309 return; 3310 } 3311 3312 incr_quickfix_busy(); 3313 3314 qfl = &qi->qf_lists[qi->qf_curlist]; 3315 3316 qf_ptr = qfl->qf_ptr; 3317 old_qf_ptr = qf_ptr; 3318 qf_index = qfl->qf_index; 3319 old_qf_index = qf_index; 3320 3321 qf_ptr = qf_get_entry(qfl, errornr, dir, &qf_index); 3322 if (qf_ptr == NULL) 3323 { 3324 qf_ptr = old_qf_ptr; 3325 qf_index = old_qf_index; 3326 goto theend; 3327 } 3328 3329 qfl->qf_index = qf_index; 3330 if (qf_win_pos_update(qi, old_qf_index)) 3331 // No need to print the error message if it's visible in the error 3332 // window 3333 print_message = FALSE; 3334 3335 prev_winid = curwin->w_id; 3336 3337 retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window); 3338 if (retval == FAIL) 3339 goto failed; 3340 if (retval == NOTDONE) 3341 goto theend; 3342 3343 retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid, 3344 &opened_window, old_KeyTyped, print_message); 3345 if (retval == NOTDONE) 3346 { 3347 // Quickfix/location list is freed by an autocmd 3348 qi = NULL; 3349 qf_ptr = NULL; 3350 } 3351 3352 if (retval != OK) 3353 { 3354 if (opened_window) 3355 win_close(curwin, TRUE); // Close opened window 3356 if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) 3357 { 3358 // Couldn't open file, so put index back where it was. This could 3359 // happen if the file was readonly and we changed something. 3360 failed: 3361 qf_ptr = old_qf_ptr; 3362 qf_index = old_qf_index; 3363 } 3364 } 3365 theend: 3366 if (qi != NULL) 3367 { 3368 qfl->qf_ptr = qf_ptr; 3369 qfl->qf_index = qf_index; 3370 } 3371 if (p_swb != old_swb) 3372 { 3373 // Restore old 'switchbuf' value, but not when an autocommand or 3374 // modeline has changed the value. 3375 if (p_swb == empty_option) 3376 { 3377 p_swb = old_swb; 3378 swb_flags = old_swb_flags; 3379 } 3380 else 3381 free_string_option(old_swb); 3382 } 3383 decr_quickfix_busy(); 3384 } 3385 3386 // Highlight attributes used for displaying entries from the quickfix list. 3387 static int qfFileAttr; 3388 static int qfSepAttr; 3389 static int qfLineAttr; 3390 3391 /* 3392 * Display information about a single entry from the quickfix/location list. 3393 * Used by ":clist/:llist" commands. 3394 * 'cursel' will be set to TRUE for the currently selected entry in the 3395 * quickfix list. 3396 */ 3397 static void 3398 qf_list_entry(qfline_T *qfp, int qf_idx, int cursel) 3399 { 3400 char_u *fname; 3401 buf_T *buf; 3402 int filter_entry; 3403 3404 fname = NULL; 3405 if (qfp->qf_module != NULL && *qfp->qf_module != NUL) 3406 vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", qf_idx, 3407 (char *)qfp->qf_module); 3408 else { 3409 if (qfp->qf_fnum != 0 3410 && (buf = buflist_findnr(qfp->qf_fnum)) != NULL) 3411 { 3412 fname = buf->b_fname; 3413 if (qfp->qf_type == 1) // :helpgrep 3414 fname = gettail(fname); 3415 } 3416 if (fname == NULL) 3417 sprintf((char *)IObuff, "%2d", qf_idx); 3418 else 3419 vim_snprintf((char *)IObuff, IOSIZE, "%2d %s", 3420 qf_idx, (char *)fname); 3421 } 3422 3423 // Support for filtering entries using :filter /pat/ clist 3424 // Match against the module name, file name, search pattern and 3425 // text of the entry. 3426 filter_entry = TRUE; 3427 if (qfp->qf_module != NULL && *qfp->qf_module != NUL) 3428 filter_entry &= message_filtered(qfp->qf_module); 3429 if (filter_entry && fname != NULL) 3430 filter_entry &= message_filtered(fname); 3431 if (filter_entry && qfp->qf_pattern != NULL) 3432 filter_entry &= message_filtered(qfp->qf_pattern); 3433 if (filter_entry) 3434 filter_entry &= message_filtered(qfp->qf_text); 3435 if (filter_entry) 3436 return; 3437 3438 msg_putchar('\n'); 3439 msg_outtrans_attr(IObuff, cursel ? HL_ATTR(HLF_QFL) : qfFileAttr); 3440 3441 if (qfp->qf_lnum != 0) 3442 msg_puts_attr(":", qfSepAttr); 3443 if (qfp->qf_lnum == 0) 3444 IObuff[0] = NUL; 3445 else if (qfp->qf_col == 0) 3446 sprintf((char *)IObuff, "%ld", qfp->qf_lnum); 3447 else 3448 sprintf((char *)IObuff, "%ld col %d", 3449 qfp->qf_lnum, qfp->qf_col); 3450 sprintf((char *)IObuff + STRLEN(IObuff), "%s", 3451 (char *)qf_types(qfp->qf_type, qfp->qf_nr)); 3452 msg_puts_attr((char *)IObuff, qfLineAttr); 3453 msg_puts_attr(":", qfSepAttr); 3454 if (qfp->qf_pattern != NULL) 3455 { 3456 qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE); 3457 msg_puts((char *)IObuff); 3458 msg_puts_attr(":", qfSepAttr); 3459 } 3460 msg_puts(" "); 3461 3462 // Remove newlines and leading whitespace from the text. For an 3463 // unrecognized line keep the indent, the compiler may mark a word 3464 // with ^^^^. 3465 qf_fmt_text((fname != NULL || qfp->qf_lnum != 0) 3466 ? skipwhite(qfp->qf_text) : qfp->qf_text, 3467 IObuff, IOSIZE); 3468 msg_prt_line(IObuff, FALSE); 3469 out_flush(); // show one line at a time 3470 } 3471 3472 /* 3473 * ":clist": list all errors 3474 * ":llist": list all locations 3475 */ 3476 void 3477 qf_list(exarg_T *eap) 3478 { 3479 qf_list_T *qfl; 3480 qfline_T *qfp; 3481 int i; 3482 int idx1 = 1; 3483 int idx2 = -1; 3484 char_u *arg = eap->arg; 3485 int plus = FALSE; 3486 int all = eap->forceit; // if not :cl!, only show 3487 // recognised errors 3488 qf_info_T *qi = &ql_info; 3489 3490 if (is_loclist_cmd(eap->cmdidx)) 3491 { 3492 qi = GET_LOC_LIST(curwin); 3493 if (qi == NULL) 3494 { 3495 emsg(_(e_loclist)); 3496 return; 3497 } 3498 } 3499 3500 if (qf_stack_empty(qi) || qf_list_empty(qi, qi->qf_curlist)) 3501 { 3502 emsg(_(e_quickfix)); 3503 return; 3504 } 3505 if (*arg == '+') 3506 { 3507 ++arg; 3508 plus = TRUE; 3509 } 3510 if (!get_list_range(&arg, &idx1, &idx2) || *arg != NUL) 3511 { 3512 emsg(_(e_trailing)); 3513 return; 3514 } 3515 qfl = &qi->qf_lists[qi->qf_curlist]; 3516 if (plus) 3517 { 3518 i = qfl->qf_index; 3519 idx2 = i + idx1; 3520 idx1 = i; 3521 } 3522 else 3523 { 3524 i = qfl->qf_count; 3525 if (idx1 < 0) 3526 idx1 = (-idx1 > i) ? 0 : idx1 + i + 1; 3527 if (idx2 < 0) 3528 idx2 = (-idx2 > i) ? 0 : idx2 + i + 1; 3529 } 3530 3531 // Shorten all the file names, so that it is easy to read 3532 shorten_fnames(FALSE); 3533 3534 // Get the attributes for the different quickfix highlight items. Note 3535 // that this depends on syntax items defined in the qf.vim syntax file 3536 qfFileAttr = syn_name2attr((char_u *)"qfFileName"); 3537 if (qfFileAttr == 0) 3538 qfFileAttr = HL_ATTR(HLF_D); 3539 qfSepAttr = syn_name2attr((char_u *)"qfSeparator"); 3540 if (qfSepAttr == 0) 3541 qfSepAttr = HL_ATTR(HLF_D); 3542 qfLineAttr = syn_name2attr((char_u *)"qfLineNr"); 3543 if (qfLineAttr == 0) 3544 qfLineAttr = HL_ATTR(HLF_N); 3545 3546 if (qfl->qf_nonevalid) 3547 all = TRUE; 3548 qfp = qfl->qf_start; 3549 for (i = 1; !got_int && i <= qfl->qf_count; ) 3550 { 3551 if ((qfp->qf_valid || all) && idx1 <= i && i <= idx2) 3552 { 3553 if (got_int) 3554 break; 3555 3556 qf_list_entry(qfp, i, i == qfl->qf_index); 3557 } 3558 3559 qfp = qfp->qf_next; 3560 if (qfp == NULL) 3561 break; 3562 ++i; 3563 ui_breakcheck(); 3564 } 3565 } 3566 3567 /* 3568 * Remove newlines and leading whitespace from an error message. 3569 * Put the result in "buf[bufsize]". 3570 */ 3571 static void 3572 qf_fmt_text(char_u *text, char_u *buf, int bufsize) 3573 { 3574 int i; 3575 char_u *p = text; 3576 3577 for (i = 0; *p != NUL && i < bufsize - 1; ++i) 3578 { 3579 if (*p == '\n') 3580 { 3581 buf[i] = ' '; 3582 while (*++p != NUL) 3583 if (!VIM_ISWHITE(*p) && *p != '\n') 3584 break; 3585 } 3586 else 3587 buf[i] = *p++; 3588 } 3589 buf[i] = NUL; 3590 } 3591 3592 /* 3593 * Display information (list number, list size and the title) about a 3594 * quickfix/location list. 3595 */ 3596 static void 3597 qf_msg(qf_info_T *qi, int which, char *lead) 3598 { 3599 char *title = (char *)qi->qf_lists[which].qf_title; 3600 int count = qi->qf_lists[which].qf_count; 3601 char_u buf[IOSIZE]; 3602 3603 vim_snprintf((char *)buf, IOSIZE, _("%serror list %d of %d; %d errors "), 3604 lead, 3605 which + 1, 3606 qi->qf_listcount, 3607 count); 3608 3609 if (title != NULL) 3610 { 3611 size_t len = STRLEN(buf); 3612 3613 if (len < 34) 3614 { 3615 vim_memset(buf + len, ' ', 34 - len); 3616 buf[34] = NUL; 3617 } 3618 vim_strcat(buf, (char_u *)title, IOSIZE); 3619 } 3620 trunc_string(buf, buf, Columns - 1, IOSIZE); 3621 msg((char *)buf); 3622 } 3623 3624 /* 3625 * ":colder [count]": Up in the quickfix stack. 3626 * ":cnewer [count]": Down in the quickfix stack. 3627 * ":lolder [count]": Up in the location list stack. 3628 * ":lnewer [count]": Down in the location list stack. 3629 */ 3630 void 3631 qf_age(exarg_T *eap) 3632 { 3633 qf_info_T *qi = &ql_info; 3634 int count; 3635 3636 if (is_loclist_cmd(eap->cmdidx)) 3637 { 3638 qi = GET_LOC_LIST(curwin); 3639 if (qi == NULL) 3640 { 3641 emsg(_(e_loclist)); 3642 return; 3643 } 3644 } 3645 3646 if (eap->addr_count != 0) 3647 count = eap->line2; 3648 else 3649 count = 1; 3650 while (count--) 3651 { 3652 if (eap->cmdidx == CMD_colder || eap->cmdidx == CMD_lolder) 3653 { 3654 if (qi->qf_curlist == 0) 3655 { 3656 emsg(_("E380: At bottom of quickfix stack")); 3657 break; 3658 } 3659 --qi->qf_curlist; 3660 } 3661 else 3662 { 3663 if (qi->qf_curlist >= qi->qf_listcount - 1) 3664 { 3665 emsg(_("E381: At top of quickfix stack")); 3666 break; 3667 } 3668 ++qi->qf_curlist; 3669 } 3670 } 3671 qf_msg(qi, qi->qf_curlist, ""); 3672 qf_update_buffer(qi, NULL); 3673 } 3674 3675 /* 3676 * Display the information about all the quickfix/location lists in the stack 3677 */ 3678 void 3679 qf_history(exarg_T *eap) 3680 { 3681 qf_info_T *qi = &ql_info; 3682 int i; 3683 3684 if (is_loclist_cmd(eap->cmdidx)) 3685 qi = GET_LOC_LIST(curwin); 3686 if (qf_stack_empty(qi)) 3687 msg(_("No entries")); 3688 else 3689 for (i = 0; i < qi->qf_listcount; ++i) 3690 qf_msg(qi, i, i == qi->qf_curlist ? "> " : " "); 3691 } 3692 3693 /* 3694 * Free all the entries in the error list "idx". Note that other information 3695 * associated with the list like context and title are not freed. 3696 */ 3697 static void 3698 qf_free_items(qf_list_T *qfl) 3699 { 3700 qfline_T *qfp; 3701 qfline_T *qfpnext; 3702 int stop = FALSE; 3703 3704 while (qfl->qf_count && qfl->qf_start != NULL) 3705 { 3706 qfp = qfl->qf_start; 3707 qfpnext = qfp->qf_next; 3708 if (!stop) 3709 { 3710 vim_free(qfp->qf_module); 3711 vim_free(qfp->qf_text); 3712 vim_free(qfp->qf_pattern); 3713 stop = (qfp == qfpnext); 3714 vim_free(qfp); 3715 if (stop) 3716 // Somehow qf_count may have an incorrect value, set it to 1 3717 // to avoid crashing when it's wrong. 3718 // TODO: Avoid qf_count being incorrect. 3719 qfl->qf_count = 1; 3720 } 3721 qfl->qf_start = qfpnext; 3722 --qfl->qf_count; 3723 } 3724 3725 qfl->qf_index = 0; 3726 qfl->qf_start = NULL; 3727 qfl->qf_last = NULL; 3728 qfl->qf_ptr = NULL; 3729 qfl->qf_nonevalid = TRUE; 3730 3731 qf_clean_dir_stack(&qfl->qf_dir_stack); 3732 qfl->qf_directory = NULL; 3733 qf_clean_dir_stack(&qfl->qf_file_stack); 3734 qfl->qf_currfile = NULL; 3735 qfl->qf_multiline = FALSE; 3736 qfl->qf_multiignore = FALSE; 3737 qfl->qf_multiscan = FALSE; 3738 } 3739 3740 /* 3741 * Free error list "idx". Frees all the entries in the quickfix list, 3742 * associated context information and the title. 3743 */ 3744 static void 3745 qf_free(qf_list_T *qfl) 3746 { 3747 qf_free_items(qfl); 3748 3749 VIM_CLEAR(qfl->qf_title); 3750 free_tv(qfl->qf_ctx); 3751 qfl->qf_ctx = NULL; 3752 qfl->qf_id = 0; 3753 qfl->qf_changedtick = 0L; 3754 } 3755 3756 /* 3757 * qf_mark_adjust: adjust marks 3758 */ 3759 void 3760 qf_mark_adjust( 3761 win_T *wp, 3762 linenr_T line1, 3763 linenr_T line2, 3764 long amount, 3765 long amount_after) 3766 { 3767 int i; 3768 qfline_T *qfp; 3769 int idx; 3770 qf_info_T *qi = &ql_info; 3771 int found_one = FALSE; 3772 int buf_has_flag = wp == NULL ? BUF_HAS_QF_ENTRY : BUF_HAS_LL_ENTRY; 3773 3774 if (!(curbuf->b_has_qf_entry & buf_has_flag)) 3775 return; 3776 if (wp != NULL) 3777 { 3778 if (wp->w_llist == NULL) 3779 return; 3780 qi = wp->w_llist; 3781 } 3782 3783 for (idx = 0; idx < qi->qf_listcount; ++idx) 3784 if (!qf_list_empty(qi, idx)) 3785 for (i = 0, qfp = qi->qf_lists[idx].qf_start; 3786 i < qi->qf_lists[idx].qf_count && qfp != NULL; 3787 ++i, qfp = qfp->qf_next) 3788 if (qfp->qf_fnum == curbuf->b_fnum) 3789 { 3790 found_one = TRUE; 3791 if (qfp->qf_lnum >= line1 && qfp->qf_lnum <= line2) 3792 { 3793 if (amount == MAXLNUM) 3794 qfp->qf_cleared = TRUE; 3795 else 3796 qfp->qf_lnum += amount; 3797 } 3798 else if (amount_after && qfp->qf_lnum > line2) 3799 qfp->qf_lnum += amount_after; 3800 } 3801 3802 if (!found_one) 3803 curbuf->b_has_qf_entry &= ~buf_has_flag; 3804 } 3805 3806 /* 3807 * Make a nice message out of the error character and the error number: 3808 * char number message 3809 * e or E 0 " error" 3810 * w or W 0 " warning" 3811 * i or I 0 " info" 3812 * 0 0 "" 3813 * other 0 " c" 3814 * e or E n " error n" 3815 * w or W n " warning n" 3816 * i or I n " info n" 3817 * 0 n " error n" 3818 * other n " c n" 3819 * 1 x "" :helpgrep 3820 */ 3821 static char_u * 3822 qf_types(int c, int nr) 3823 { 3824 static char_u buf[20]; 3825 static char_u cc[3]; 3826 char_u *p; 3827 3828 if (c == 'W' || c == 'w') 3829 p = (char_u *)" warning"; 3830 else if (c == 'I' || c == 'i') 3831 p = (char_u *)" info"; 3832 else if (c == 'E' || c == 'e' || (c == 0 && nr > 0)) 3833 p = (char_u *)" error"; 3834 else if (c == 0 || c == 1) 3835 p = (char_u *)""; 3836 else 3837 { 3838 cc[0] = ' '; 3839 cc[1] = c; 3840 cc[2] = NUL; 3841 p = cc; 3842 } 3843 3844 if (nr <= 0) 3845 return p; 3846 3847 sprintf((char *)buf, "%s %3d", (char *)p, nr); 3848 return buf; 3849 } 3850 3851 /* 3852 * When "split" is FALSE: Open the entry/result under the cursor. 3853 * When "split" is TRUE: Open the entry/result under the cursor in a new window. 3854 */ 3855 void 3856 qf_view_result(int split) 3857 { 3858 qf_info_T *qi = &ql_info; 3859 3860 if (!bt_quickfix(curbuf)) 3861 return; 3862 3863 if (IS_LL_WINDOW(curwin)) 3864 qi = GET_LOC_LIST(curwin); 3865 3866 if (qf_list_empty(qi, qi->qf_curlist)) 3867 { 3868 emsg(_(e_quickfix)); 3869 return; 3870 } 3871 3872 if (split) 3873 { 3874 // Open the selected entry in a new window 3875 qf_jump_newwin(qi, 0, (long)curwin->w_cursor.lnum, FALSE, TRUE); 3876 do_cmdline_cmd((char_u *) "clearjumps"); 3877 return; 3878 } 3879 3880 do_cmdline_cmd((char_u *)(IS_LL_WINDOW(curwin) ? ".ll" : ".cc")); 3881 } 3882 3883 /* 3884 * ":cwindow": open the quickfix window if we have errors to display, 3885 * close it if not. 3886 * ":lwindow": open the location list window if we have locations to display, 3887 * close it if not. 3888 */ 3889 void 3890 ex_cwindow(exarg_T *eap) 3891 { 3892 qf_info_T *qi = &ql_info; 3893 qf_list_T *qfl; 3894 win_T *win; 3895 3896 if (is_loclist_cmd(eap->cmdidx)) 3897 { 3898 qi = GET_LOC_LIST(curwin); 3899 if (qi == NULL) 3900 return; 3901 } 3902 3903 qfl = &qi->qf_lists[qi->qf_curlist]; 3904 3905 // Look for an existing quickfix window. 3906 win = qf_find_win(qi); 3907 3908 // If a quickfix window is open but we have no errors to display, 3909 // close the window. If a quickfix window is not open, then open 3910 // it if we have errors; otherwise, leave it closed. 3911 if (qf_stack_empty(qi) 3912 || qfl->qf_nonevalid 3913 || qf_list_empty(qi, qi->qf_curlist)) 3914 { 3915 if (win != NULL) 3916 ex_cclose(eap); 3917 } 3918 else if (win == NULL) 3919 ex_copen(eap); 3920 } 3921 3922 /* 3923 * ":cclose": close the window showing the list of errors. 3924 * ":lclose": close the window showing the location list 3925 */ 3926 void 3927 ex_cclose(exarg_T *eap) 3928 { 3929 win_T *win = NULL; 3930 qf_info_T *qi = &ql_info; 3931 3932 if (is_loclist_cmd(eap->cmdidx)) 3933 { 3934 qi = GET_LOC_LIST(curwin); 3935 if (qi == NULL) 3936 return; 3937 } 3938 3939 // Find existing quickfix window and close it. 3940 win = qf_find_win(qi); 3941 if (win != NULL) 3942 win_close(win, FALSE); 3943 } 3944 3945 /* 3946 * Set "w:quickfix_title" if "qi" has a title. 3947 */ 3948 static void 3949 qf_set_title_var(qf_list_T *qfl) 3950 { 3951 if (qfl->qf_title != NULL) 3952 set_internal_string_var((char_u *)"w:quickfix_title", qfl->qf_title); 3953 } 3954 3955 /* 3956 * Goto a quickfix or location list window (if present). 3957 * Returns OK if the window is found, FAIL otherwise. 3958 */ 3959 static int 3960 qf_goto_cwindow(qf_info_T *qi, int resize, int sz, int vertsplit) 3961 { 3962 win_T *win; 3963 3964 win = qf_find_win(qi); 3965 if (win == NULL) 3966 return FAIL; 3967 3968 win_goto(win); 3969 if (resize) 3970 { 3971 if (vertsplit) 3972 { 3973 if (sz != win->w_width) 3974 win_setwidth(sz); 3975 } 3976 else if (sz != win->w_height) 3977 win_setheight(sz); 3978 } 3979 3980 return OK; 3981 } 3982 3983 /* 3984 * Open a new quickfix or location list window, load the quickfix buffer and 3985 * set the appropriate options for the window. 3986 * Returns FAIL if the window could not be opened. 3987 */ 3988 static int 3989 qf_open_new_cwindow(qf_info_T *qi, int height) 3990 { 3991 buf_T *qf_buf; 3992 win_T *oldwin = curwin; 3993 tabpage_T *prevtab = curtab; 3994 int flags = 0; 3995 win_T *win; 3996 3997 qf_buf = qf_find_buf(qi); 3998 3999 // The current window becomes the previous window afterwards. 4000 win = curwin; 4001 4002 if (IS_QF_STACK(qi) && cmdmod.split == 0) 4003 // Create the new quickfix window at the very bottom, except when 4004 // :belowright or :aboveleft is used. 4005 win_goto(lastwin); 4006 // Default is to open the window below the current window 4007 if (cmdmod.split == 0) 4008 flags = WSP_BELOW; 4009 flags |= WSP_NEWLOC; 4010 if (win_split(height, flags) == FAIL) 4011 return FAIL; // not enough room for window 4012 RESET_BINDING(curwin); 4013 4014 if (IS_LL_STACK(qi)) 4015 { 4016 // For the location list window, create a reference to the 4017 // location list stack from the window 'win'. 4018 curwin->w_llist_ref = qi; 4019 qi->qf_refcount++; 4020 } 4021 4022 if (oldwin != curwin) 4023 oldwin = NULL; // don't store info when in another window 4024 if (qf_buf != NULL) 4025 { 4026 // Use the existing quickfix buffer 4027 (void)do_ecmd(qf_buf->b_fnum, NULL, NULL, NULL, ECMD_ONE, 4028 ECMD_HIDE + ECMD_OLDBUF, oldwin); 4029 } 4030 else 4031 { 4032 // Create a new quickfix buffer 4033 (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, oldwin); 4034 4035 // switch off 'swapfile' 4036 set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL); 4037 set_option_value((char_u *)"bt", 0L, (char_u *)"quickfix", 4038 OPT_LOCAL); 4039 set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL); 4040 RESET_BINDING(curwin); 4041 #ifdef FEAT_DIFF 4042 curwin->w_p_diff = FALSE; 4043 #endif 4044 #ifdef FEAT_FOLDING 4045 set_option_value((char_u *)"fdm", 0L, (char_u *)"manual", 4046 OPT_LOCAL); 4047 #endif 4048 // save the number of the new buffer 4049 qi->qf_bufnr = curbuf->b_fnum; 4050 } 4051 4052 // Only set the height when still in the same tab page and there is no 4053 // window to the side. 4054 if (curtab == prevtab && curwin->w_width == Columns) 4055 win_setheight(height); 4056 curwin->w_p_wfh = TRUE; // set 'winfixheight' 4057 if (win_valid(win)) 4058 prevwin = win; 4059 4060 return OK; 4061 } 4062 4063 /* 4064 * ":copen": open a window that shows the list of errors. 4065 * ":lopen": open a window that shows the location list. 4066 */ 4067 void 4068 ex_copen(exarg_T *eap) 4069 { 4070 qf_info_T *qi = &ql_info; 4071 qf_list_T *qfl; 4072 int height; 4073 int status = FAIL; 4074 int lnum; 4075 4076 if (is_loclist_cmd(eap->cmdidx)) 4077 { 4078 qi = GET_LOC_LIST(curwin); 4079 if (qi == NULL) 4080 { 4081 emsg(_(e_loclist)); 4082 return; 4083 } 4084 } 4085 4086 incr_quickfix_busy(); 4087 4088 if (eap->addr_count != 0) 4089 height = eap->line2; 4090 else 4091 height = QF_WINHEIGHT; 4092 4093 reset_VIsual_and_resel(); // stop Visual mode 4094 #ifdef FEAT_GUI 4095 need_mouse_correct = TRUE; 4096 #endif 4097 4098 // Find an existing quickfix window, or open a new one. 4099 if (cmdmod.tab == 0) 4100 status = qf_goto_cwindow(qi, eap->addr_count != 0, height, 4101 cmdmod.split & WSP_VERT); 4102 if (status == FAIL) 4103 if (qf_open_new_cwindow(qi, height) == FAIL) 4104 { 4105 decr_quickfix_busy(); 4106 return; 4107 } 4108 4109 qfl = &qi->qf_lists[qi->qf_curlist]; 4110 qf_set_title_var(qfl); 4111 // Save the current index here, as updating the quickfix buffer may free 4112 // the quickfix list 4113 lnum = qfl->qf_index; 4114 4115 // Fill the buffer with the quickfix list. 4116 qf_fill_buffer(qi, curbuf, NULL); 4117 4118 decr_quickfix_busy(); 4119 4120 curwin->w_cursor.lnum = lnum; 4121 curwin->w_cursor.col = 0; 4122 check_cursor(); 4123 update_topline(); // scroll to show the line 4124 } 4125 4126 /* 4127 * Move the cursor in the quickfix window to "lnum". 4128 */ 4129 static void 4130 qf_win_goto(win_T *win, linenr_T lnum) 4131 { 4132 win_T *old_curwin = curwin; 4133 4134 curwin = win; 4135 curbuf = win->w_buffer; 4136 curwin->w_cursor.lnum = lnum; 4137 curwin->w_cursor.col = 0; 4138 curwin->w_cursor.coladd = 0; 4139 curwin->w_curswant = 0; 4140 update_topline(); // scroll to show the line 4141 redraw_later(VALID); 4142 curwin->w_redr_status = TRUE; // update ruler 4143 curwin = old_curwin; 4144 curbuf = curwin->w_buffer; 4145 } 4146 4147 /* 4148 * :cbottom/:lbottom commands. 4149 */ 4150 void 4151 ex_cbottom(exarg_T *eap) 4152 { 4153 qf_info_T *qi = &ql_info; 4154 win_T *win; 4155 4156 if (is_loclist_cmd(eap->cmdidx)) 4157 { 4158 qi = GET_LOC_LIST(curwin); 4159 if (qi == NULL) 4160 { 4161 emsg(_(e_loclist)); 4162 return; 4163 } 4164 } 4165 4166 win = qf_find_win(qi); 4167 if (win != NULL && win->w_cursor.lnum != win->w_buffer->b_ml.ml_line_count) 4168 qf_win_goto(win, win->w_buffer->b_ml.ml_line_count); 4169 } 4170 4171 /* 4172 * Return the number of the current entry (line number in the quickfix 4173 * window). 4174 */ 4175 linenr_T 4176 qf_current_entry(win_T *wp) 4177 { 4178 qf_info_T *qi = &ql_info; 4179 4180 if (IS_LL_WINDOW(wp)) 4181 // In the location list window, use the referenced location list 4182 qi = wp->w_llist_ref; 4183 4184 return qi->qf_lists[qi->qf_curlist].qf_index; 4185 } 4186 4187 /* 4188 * Update the cursor position in the quickfix window to the current error. 4189 * Return TRUE if there is a quickfix window. 4190 */ 4191 static int 4192 qf_win_pos_update( 4193 qf_info_T *qi, 4194 int old_qf_index) // previous qf_index or zero 4195 { 4196 win_T *win; 4197 int qf_index = qi->qf_lists[qi->qf_curlist].qf_index; 4198 4199 // Put the cursor on the current error in the quickfix window, so that 4200 // it's viewable. 4201 win = qf_find_win(qi); 4202 if (win != NULL 4203 && qf_index <= win->w_buffer->b_ml.ml_line_count 4204 && old_qf_index != qf_index) 4205 { 4206 if (qf_index > old_qf_index) 4207 { 4208 win->w_redraw_top = old_qf_index; 4209 win->w_redraw_bot = qf_index; 4210 } 4211 else 4212 { 4213 win->w_redraw_top = qf_index; 4214 win->w_redraw_bot = old_qf_index; 4215 } 4216 qf_win_goto(win, qf_index); 4217 } 4218 return win != NULL; 4219 } 4220 4221 /* 4222 * Check whether the given window is displaying the specified quickfix/location 4223 * stack. 4224 */ 4225 static int 4226 is_qf_win(win_T *win, qf_info_T *qi) 4227 { 4228 // A window displaying the quickfix buffer will have the w_llist_ref field 4229 // set to NULL. 4230 // A window displaying a location list buffer will have the w_llist_ref 4231 // pointing to the location list. 4232 if (bt_quickfix(win->w_buffer)) 4233 if ((IS_QF_STACK(qi) && win->w_llist_ref == NULL) 4234 || (IS_LL_STACK(qi) && win->w_llist_ref == qi)) 4235 return TRUE; 4236 4237 return FALSE; 4238 } 4239 4240 /* 4241 * Find a window displaying the quickfix/location stack 'qi' 4242 * Only searches in the current tabpage. 4243 */ 4244 static win_T * 4245 qf_find_win(qf_info_T *qi) 4246 { 4247 win_T *win; 4248 4249 FOR_ALL_WINDOWS(win) 4250 if (is_qf_win(win, qi)) 4251 return win; 4252 return NULL; 4253 } 4254 4255 /* 4256 * Find a quickfix buffer. 4257 * Searches in windows opened in all the tabs. 4258 */ 4259 static buf_T * 4260 qf_find_buf(qf_info_T *qi) 4261 { 4262 tabpage_T *tp; 4263 win_T *win; 4264 4265 if (qi->qf_bufnr != INVALID_QFBUFNR) 4266 { 4267 buf_T *qfbuf; 4268 qfbuf = buflist_findnr(qi->qf_bufnr); 4269 if (qfbuf != NULL) 4270 return qfbuf; 4271 // buffer is no longer present 4272 qi->qf_bufnr = INVALID_QFBUFNR; 4273 } 4274 4275 FOR_ALL_TAB_WINDOWS(tp, win) 4276 if (is_qf_win(win, qi)) 4277 return win->w_buffer; 4278 4279 return NULL; 4280 } 4281 4282 /* 4283 * Update the w:quickfix_title variable in the quickfix/location list window 4284 */ 4285 static void 4286 qf_update_win_titlevar(qf_info_T *qi) 4287 { 4288 win_T *win; 4289 win_T *curwin_save; 4290 4291 if ((win = qf_find_win(qi)) != NULL) 4292 { 4293 curwin_save = curwin; 4294 curwin = win; 4295 qf_set_title_var(&qi->qf_lists[qi->qf_curlist]); 4296 curwin = curwin_save; 4297 } 4298 } 4299 4300 /* 4301 * Find the quickfix buffer. If it exists, update the contents. 4302 */ 4303 static void 4304 qf_update_buffer(qf_info_T *qi, qfline_T *old_last) 4305 { 4306 buf_T *buf; 4307 win_T *win; 4308 aco_save_T aco; 4309 4310 // Check if a buffer for the quickfix list exists. Update it. 4311 buf = qf_find_buf(qi); 4312 if (buf != NULL) 4313 { 4314 linenr_T old_line_count = buf->b_ml.ml_line_count; 4315 4316 if (old_last == NULL) 4317 // set curwin/curbuf to buf and save a few things 4318 aucmd_prepbuf(&aco, buf); 4319 4320 qf_update_win_titlevar(qi); 4321 4322 qf_fill_buffer(qi, buf, old_last); 4323 ++CHANGEDTICK(buf); 4324 4325 if (old_last == NULL) 4326 { 4327 (void)qf_win_pos_update(qi, 0); 4328 4329 // restore curwin/curbuf and a few other things 4330 aucmd_restbuf(&aco); 4331 } 4332 4333 // Only redraw when added lines are visible. This avoids flickering 4334 // when the added lines are not visible. 4335 if ((win = qf_find_win(qi)) != NULL && old_line_count < win->w_botline) 4336 redraw_buf_later(buf, NOT_VALID); 4337 } 4338 } 4339 4340 /* 4341 * Add an error line to the quickfix buffer. 4342 */ 4343 static int 4344 qf_buf_add_line(buf_T *buf, linenr_T lnum, qfline_T *qfp, char_u *dirname) 4345 { 4346 int len; 4347 buf_T *errbuf; 4348 4349 if (qfp->qf_module != NULL) 4350 { 4351 STRCPY(IObuff, qfp->qf_module); 4352 len = (int)STRLEN(IObuff); 4353 } 4354 else if (qfp->qf_fnum != 0 4355 && (errbuf = buflist_findnr(qfp->qf_fnum)) != NULL 4356 && errbuf->b_fname != NULL) 4357 { 4358 if (qfp->qf_type == 1) // :helpgrep 4359 STRCPY(IObuff, gettail(errbuf->b_fname)); 4360 else 4361 { 4362 // shorten the file name if not done already 4363 if (errbuf->b_sfname == NULL 4364 || mch_isFullName(errbuf->b_sfname)) 4365 { 4366 if (*dirname == NUL) 4367 mch_dirname(dirname, MAXPATHL); 4368 shorten_buf_fname(errbuf, dirname, FALSE); 4369 } 4370 STRCPY(IObuff, errbuf->b_fname); 4371 } 4372 len = (int)STRLEN(IObuff); 4373 } 4374 else 4375 len = 0; 4376 IObuff[len++] = '|'; 4377 4378 if (qfp->qf_lnum > 0) 4379 { 4380 sprintf((char *)IObuff + len, "%ld", qfp->qf_lnum); 4381 len += (int)STRLEN(IObuff + len); 4382 4383 if (qfp->qf_col > 0) 4384 { 4385 sprintf((char *)IObuff + len, " col %d", qfp->qf_col); 4386 len += (int)STRLEN(IObuff + len); 4387 } 4388 4389 sprintf((char *)IObuff + len, "%s", 4390 (char *)qf_types(qfp->qf_type, qfp->qf_nr)); 4391 len += (int)STRLEN(IObuff + len); 4392 } 4393 else if (qfp->qf_pattern != NULL) 4394 { 4395 qf_fmt_text(qfp->qf_pattern, IObuff + len, IOSIZE - len); 4396 len += (int)STRLEN(IObuff + len); 4397 } 4398 IObuff[len++] = '|'; 4399 IObuff[len++] = ' '; 4400 4401 // Remove newlines and leading whitespace from the text. 4402 // For an unrecognized line keep the indent, the compiler may 4403 // mark a word with ^^^^. 4404 qf_fmt_text(len > 3 ? skipwhite(qfp->qf_text) : qfp->qf_text, 4405 IObuff + len, IOSIZE - len); 4406 4407 if (ml_append_buf(buf, lnum, IObuff, 4408 (colnr_T)STRLEN(IObuff) + 1, FALSE) == FAIL) 4409 return FAIL; 4410 4411 return OK; 4412 } 4413 4414 /* 4415 * Fill current buffer with quickfix errors, replacing any previous contents. 4416 * curbuf must be the quickfix buffer! 4417 * If "old_last" is not NULL append the items after this one. 4418 * When "old_last" is NULL then "buf" must equal "curbuf"! Because 4419 * ml_delete() is used and autocommands will be triggered. 4420 */ 4421 static void 4422 qf_fill_buffer(qf_info_T *qi, buf_T *buf, qfline_T *old_last) 4423 { 4424 linenr_T lnum; 4425 qfline_T *qfp; 4426 int old_KeyTyped = KeyTyped; 4427 4428 if (old_last == NULL) 4429 { 4430 if (buf != curbuf) 4431 { 4432 internal_error("qf_fill_buffer()"); 4433 return; 4434 } 4435 4436 // delete all existing lines 4437 while ((curbuf->b_ml.ml_flags & ML_EMPTY) == 0) 4438 (void)ml_delete((linenr_T)1, FALSE); 4439 } 4440 4441 // Check if there is anything to display 4442 if (!qf_stack_empty(qi)) 4443 { 4444 qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; 4445 char_u dirname[MAXPATHL]; 4446 4447 *dirname = NUL; 4448 4449 // Add one line for each error 4450 if (old_last == NULL) 4451 { 4452 qfp = qfl->qf_start; 4453 lnum = 0; 4454 } 4455 else 4456 { 4457 qfp = old_last->qf_next; 4458 lnum = buf->b_ml.ml_line_count; 4459 } 4460 while (lnum < qfl->qf_count) 4461 { 4462 if (qf_buf_add_line(buf, lnum, qfp, dirname) == FAIL) 4463 break; 4464 4465 ++lnum; 4466 qfp = qfp->qf_next; 4467 if (qfp == NULL) 4468 break; 4469 } 4470 4471 if (old_last == NULL) 4472 // Delete the empty line which is now at the end 4473 (void)ml_delete(lnum + 1, FALSE); 4474 } 4475 4476 // correct cursor position 4477 check_lnums(TRUE); 4478 4479 if (old_last == NULL) 4480 { 4481 // Set the 'filetype' to "qf" each time after filling the buffer. 4482 // This resembles reading a file into a buffer, it's more logical when 4483 // using autocommands. 4484 ++curbuf_lock; 4485 set_option_value((char_u *)"ft", 0L, (char_u *)"qf", OPT_LOCAL); 4486 curbuf->b_p_ma = FALSE; 4487 4488 keep_filetype = TRUE; // don't detect 'filetype' 4489 apply_autocmds(EVENT_BUFREADPOST, (char_u *)"quickfix", NULL, 4490 FALSE, curbuf); 4491 apply_autocmds(EVENT_BUFWINENTER, (char_u *)"quickfix", NULL, 4492 FALSE, curbuf); 4493 keep_filetype = FALSE; 4494 --curbuf_lock; 4495 4496 // make sure it will be redrawn 4497 redraw_curbuf_later(NOT_VALID); 4498 } 4499 4500 // Restore KeyTyped, setting 'filetype' may reset it. 4501 KeyTyped = old_KeyTyped; 4502 } 4503 4504 /* 4505 * For every change made to the quickfix list, update the changed tick. 4506 */ 4507 static void 4508 qf_list_changed(qf_list_T *qfl) 4509 { 4510 qfl->qf_changedtick++; 4511 } 4512 4513 /* 4514 * Return the quickfix/location list number with the given identifier. 4515 * Returns -1 if list is not found. 4516 */ 4517 static int 4518 qf_id2nr(qf_info_T *qi, int_u qfid) 4519 { 4520 int qf_idx; 4521 4522 for (qf_idx = 0; qf_idx < qi->qf_listcount; qf_idx++) 4523 if (qi->qf_lists[qf_idx].qf_id == qfid) 4524 return qf_idx; 4525 return INVALID_QFIDX; 4526 } 4527 4528 /* 4529 * If the current list is not "save_qfid" and we can find the list with that ID 4530 * then make it the current list. 4531 * This is used when autocommands may have changed the current list. 4532 * Returns OK if successfully restored the list. Returns FAIL if the list with 4533 * the specified identifier (save_qfid) is not found in the stack. 4534 */ 4535 static int 4536 qf_restore_list(qf_info_T *qi, int_u save_qfid) 4537 { 4538 int curlist; 4539 4540 if (qi->qf_lists[qi->qf_curlist].qf_id != save_qfid) 4541 { 4542 curlist = qf_id2nr(qi, save_qfid); 4543 if (curlist < 0) 4544 // list is not present 4545 return FAIL; 4546 qi->qf_curlist = curlist; 4547 } 4548 return OK; 4549 } 4550 4551 /* 4552 * Jump to the first entry if there is one. 4553 */ 4554 static void 4555 qf_jump_first(qf_info_T *qi, int_u save_qfid, int forceit) 4556 { 4557 if (qf_restore_list(qi, save_qfid) == FAIL) 4558 return; 4559 4560 // Autocommands might have cleared the list, check for that. 4561 if (!qf_list_empty(qi, qi->qf_curlist)) 4562 qf_jump(qi, 0, 0, forceit); 4563 } 4564 4565 /* 4566 * Return TRUE when using ":vimgrep" for ":grep". 4567 */ 4568 int 4569 grep_internal(cmdidx_T cmdidx) 4570 { 4571 return ((cmdidx == CMD_grep 4572 || cmdidx == CMD_lgrep 4573 || cmdidx == CMD_grepadd 4574 || cmdidx == CMD_lgrepadd) 4575 && STRCMP("internal", 4576 *curbuf->b_p_gp == NUL ? p_gp : curbuf->b_p_gp) == 0); 4577 } 4578 4579 /* 4580 * Return the make/grep autocmd name. 4581 */ 4582 static char_u * 4583 make_get_auname(cmdidx_T cmdidx) 4584 { 4585 switch (cmdidx) 4586 { 4587 case CMD_make: return (char_u *)"make"; 4588 case CMD_lmake: return (char_u *)"lmake"; 4589 case CMD_grep: return (char_u *)"grep"; 4590 case CMD_lgrep: return (char_u *)"lgrep"; 4591 case CMD_grepadd: return (char_u *)"grepadd"; 4592 case CMD_lgrepadd: return (char_u *)"lgrepadd"; 4593 default: return NULL; 4594 } 4595 } 4596 4597 /* 4598 * Return the name for the errorfile, in allocated memory. 4599 * Find a new unique name when 'makeef' contains "##". 4600 * Returns NULL for error. 4601 */ 4602 static char_u * 4603 get_mef_name(void) 4604 { 4605 char_u *p; 4606 char_u *name; 4607 static int start = -1; 4608 static int off = 0; 4609 #ifdef HAVE_LSTAT 4610 stat_T sb; 4611 #endif 4612 4613 if (*p_mef == NUL) 4614 { 4615 name = vim_tempname('e', FALSE); 4616 if (name == NULL) 4617 emsg(_(e_notmp)); 4618 return name; 4619 } 4620 4621 for (p = p_mef; *p; ++p) 4622 if (p[0] == '#' && p[1] == '#') 4623 break; 4624 4625 if (*p == NUL) 4626 return vim_strsave(p_mef); 4627 4628 // Keep trying until the name doesn't exist yet. 4629 for (;;) 4630 { 4631 if (start == -1) 4632 start = mch_get_pid(); 4633 else 4634 off += 19; 4635 4636 name = alloc((unsigned)STRLEN(p_mef) + 30); 4637 if (name == NULL) 4638 break; 4639 STRCPY(name, p_mef); 4640 sprintf((char *)name + (p - p_mef), "%d%d", start, off); 4641 STRCAT(name, p + 2); 4642 if (mch_getperm(name) < 0 4643 #ifdef HAVE_LSTAT 4644 // Don't accept a symbolic link, it's a security risk. 4645 && mch_lstat((char *)name, &sb) < 0 4646 #endif 4647 ) 4648 break; 4649 vim_free(name); 4650 } 4651 return name; 4652 } 4653 4654 /* 4655 * Form the complete command line to invoke 'make'/'grep'. Quote the command 4656 * using 'shellquote' and append 'shellpipe'. Echo the fully formed command. 4657 */ 4658 static char_u * 4659 make_get_fullcmd(char_u *makecmd, char_u *fname) 4660 { 4661 char_u *cmd; 4662 unsigned len; 4663 4664 len = (unsigned)STRLEN(p_shq) * 2 + (unsigned)STRLEN(makecmd) + 1; 4665 if (*p_sp != NUL) 4666 len += (unsigned)STRLEN(p_sp) + (unsigned)STRLEN(fname) + 3; 4667 cmd = alloc(len); 4668 if (cmd == NULL) 4669 return NULL; 4670 sprintf((char *)cmd, "%s%s%s", (char *)p_shq, (char *)makecmd, 4671 (char *)p_shq); 4672 4673 // If 'shellpipe' empty: don't redirect to 'errorfile'. 4674 if (*p_sp != NUL) 4675 append_redir(cmd, len, p_sp, fname); 4676 4677 // Display the fully formed command. Output a newline if there's something 4678 // else than the :make command that was typed (in which case the cursor is 4679 // in column 0). 4680 if (msg_col == 0) 4681 msg_didout = FALSE; 4682 msg_start(); 4683 msg_puts(":!"); 4684 msg_outtrans(cmd); // show what we are doing 4685 4686 return cmd; 4687 } 4688 4689 /* 4690 * Used for ":make", ":lmake", ":grep", ":lgrep", ":grepadd", and ":lgrepadd" 4691 */ 4692 void 4693 ex_make(exarg_T *eap) 4694 { 4695 char_u *fname; 4696 char_u *cmd; 4697 char_u *enc = NULL; 4698 win_T *wp = NULL; 4699 qf_info_T *qi = &ql_info; 4700 int res; 4701 char_u *au_name = NULL; 4702 int_u save_qfid; 4703 4704 // Redirect ":grep" to ":vimgrep" if 'grepprg' is "internal". 4705 if (grep_internal(eap->cmdidx)) 4706 { 4707 ex_vimgrep(eap); 4708 return; 4709 } 4710 4711 au_name = make_get_auname(eap->cmdidx); 4712 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, 4713 curbuf->b_fname, TRUE, curbuf)) 4714 { 4715 #ifdef FEAT_EVAL 4716 if (aborting()) 4717 return; 4718 #endif 4719 } 4720 enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; 4721 4722 if (is_loclist_cmd(eap->cmdidx)) 4723 wp = curwin; 4724 4725 autowrite_all(); 4726 fname = get_mef_name(); 4727 if (fname == NULL) 4728 return; 4729 mch_remove(fname); // in case it's not unique 4730 4731 cmd = make_get_fullcmd(eap->arg, fname); 4732 if (cmd == NULL) 4733 return; 4734 4735 // let the shell know if we are redirecting output or not 4736 do_shell(cmd, *p_sp != NUL ? SHELL_DOOUT : 0); 4737 4738 #ifdef AMIGA 4739 out_flush(); 4740 // read window status report and redraw before message 4741 (void)char_avail(); 4742 #endif 4743 4744 incr_quickfix_busy(); 4745 4746 res = qf_init(wp, fname, (eap->cmdidx != CMD_make 4747 && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm, 4748 (eap->cmdidx != CMD_grepadd 4749 && eap->cmdidx != CMD_lgrepadd), 4750 qf_cmdtitle(*eap->cmdlinep), enc); 4751 if (wp != NULL) 4752 { 4753 qi = GET_LOC_LIST(wp); 4754 if (qi == NULL) 4755 goto cleanup; 4756 } 4757 if (res >= 0) 4758 qf_list_changed(&qi->qf_lists[qi->qf_curlist]); 4759 4760 // Remember the current quickfix list identifier, so that we can 4761 // check for autocommands changing the current quickfix list. 4762 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 4763 if (au_name != NULL) 4764 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, 4765 curbuf->b_fname, TRUE, curbuf); 4766 if (res > 0 && !eap->forceit && qflist_valid(wp, save_qfid)) 4767 // display the first error 4768 qf_jump_first(qi, save_qfid, FALSE); 4769 4770 cleanup: 4771 decr_quickfix_busy(); 4772 mch_remove(fname); 4773 vim_free(fname); 4774 vim_free(cmd); 4775 } 4776 4777 /* 4778 * Returns the number of valid entries in the current quickfix/location list. 4779 */ 4780 int 4781 qf_get_size(exarg_T *eap) 4782 { 4783 qf_info_T *qi = &ql_info; 4784 qf_list_T *qfl; 4785 qfline_T *qfp; 4786 int i, sz = 0; 4787 int prev_fnum = 0; 4788 4789 if (is_loclist_cmd(eap->cmdidx)) 4790 { 4791 // Location list 4792 qi = GET_LOC_LIST(curwin); 4793 if (qi == NULL) 4794 return 0; 4795 } 4796 4797 qfl = &qi->qf_lists[qi->qf_curlist]; 4798 for (i = 0, qfp = qfl->qf_start; i < qfl->qf_count && qfp != NULL; 4799 ++i, qfp = qfp->qf_next) 4800 { 4801 if (qfp->qf_valid) 4802 { 4803 if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo) 4804 sz++; // Count all valid entries 4805 else if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) 4806 { 4807 // Count the number of files 4808 sz++; 4809 prev_fnum = qfp->qf_fnum; 4810 } 4811 } 4812 } 4813 4814 return sz; 4815 } 4816 4817 /* 4818 * Returns the current index of the quickfix/location list. 4819 * Returns 0 if there is an error. 4820 */ 4821 int 4822 qf_get_cur_idx(exarg_T *eap) 4823 { 4824 qf_info_T *qi = &ql_info; 4825 4826 if (is_loclist_cmd(eap->cmdidx)) 4827 { 4828 // Location list 4829 qi = GET_LOC_LIST(curwin); 4830 if (qi == NULL) 4831 return 0; 4832 } 4833 4834 return qi->qf_lists[qi->qf_curlist].qf_index; 4835 } 4836 4837 /* 4838 * Returns the current index in the quickfix/location list (counting only valid 4839 * entries). If no valid entries are in the list, then returns 1. 4840 */ 4841 int 4842 qf_get_cur_valid_idx(exarg_T *eap) 4843 { 4844 qf_info_T *qi = &ql_info; 4845 qf_list_T *qfl; 4846 qfline_T *qfp; 4847 int i, eidx = 0; 4848 int prev_fnum = 0; 4849 4850 if (is_loclist_cmd(eap->cmdidx)) 4851 { 4852 // Location list 4853 qi = GET_LOC_LIST(curwin); 4854 if (qi == NULL) 4855 return 1; 4856 } 4857 4858 qfl = &qi->qf_lists[qi->qf_curlist]; 4859 qfp = qfl->qf_start; 4860 4861 // check if the list has valid errors 4862 if (qfl->qf_count <= 0 || qfl->qf_nonevalid) 4863 return 1; 4864 4865 for (i = 1; i <= qfl->qf_index && qfp!= NULL; i++, qfp = qfp->qf_next) 4866 { 4867 if (qfp->qf_valid) 4868 { 4869 if (eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) 4870 { 4871 if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) 4872 { 4873 // Count the number of files 4874 eidx++; 4875 prev_fnum = qfp->qf_fnum; 4876 } 4877 } 4878 else 4879 eidx++; 4880 } 4881 } 4882 4883 return eidx ? eidx : 1; 4884 } 4885 4886 /* 4887 * Get the 'n'th valid error entry in the quickfix or location list. 4888 * Used by :cdo, :ldo, :cfdo and :lfdo commands. 4889 * For :cdo and :ldo returns the 'n'th valid error entry. 4890 * For :cfdo and :lfdo returns the 'n'th valid file entry. 4891 */ 4892 static int 4893 qf_get_nth_valid_entry(qf_list_T *qfl, int n, int fdo) 4894 { 4895 qfline_T *qfp = qfl->qf_start; 4896 int i, eidx; 4897 int prev_fnum = 0; 4898 4899 // check if the list has valid errors 4900 if (qfl->qf_count <= 0 || qfl->qf_nonevalid) 4901 return 1; 4902 4903 for (i = 1, eidx = 0; i <= qfl->qf_count && qfp != NULL; 4904 i++, qfp = qfp->qf_next) 4905 { 4906 if (qfp->qf_valid) 4907 { 4908 if (fdo) 4909 { 4910 if (qfp->qf_fnum > 0 && qfp->qf_fnum != prev_fnum) 4911 { 4912 // Count the number of files 4913 eidx++; 4914 prev_fnum = qfp->qf_fnum; 4915 } 4916 } 4917 else 4918 eidx++; 4919 } 4920 4921 if (eidx == n) 4922 break; 4923 } 4924 4925 if (i <= qfl->qf_count) 4926 return i; 4927 else 4928 return 1; 4929 } 4930 4931 /* 4932 * ":cc", ":crewind", ":cfirst" and ":clast". 4933 * ":ll", ":lrewind", ":lfirst" and ":llast". 4934 * ":cdo", ":ldo", ":cfdo" and ":lfdo" 4935 */ 4936 void 4937 ex_cc(exarg_T *eap) 4938 { 4939 qf_info_T *qi = &ql_info; 4940 int errornr; 4941 4942 if (is_loclist_cmd(eap->cmdidx)) 4943 { 4944 qi = GET_LOC_LIST(curwin); 4945 if (qi == NULL) 4946 { 4947 emsg(_(e_loclist)); 4948 return; 4949 } 4950 } 4951 4952 if (eap->addr_count > 0) 4953 errornr = (int)eap->line2; 4954 else 4955 { 4956 switch (eap->cmdidx) 4957 { 4958 case CMD_cc: case CMD_ll: 4959 errornr = 0; 4960 break; 4961 case CMD_crewind: case CMD_lrewind: case CMD_cfirst: 4962 case CMD_lfirst: 4963 errornr = 1; 4964 break; 4965 default: 4966 errornr = 32767; 4967 } 4968 } 4969 4970 // For cdo and ldo commands, jump to the nth valid error. 4971 // For cfdo and lfdo commands, jump to the nth valid file entry. 4972 if (eap->cmdidx == CMD_cdo || eap->cmdidx == CMD_ldo 4973 || eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo) 4974 errornr = qf_get_nth_valid_entry(&qi->qf_lists[qi->qf_curlist], 4975 eap->addr_count > 0 ? (int)eap->line1 : 1, 4976 eap->cmdidx == CMD_cfdo || eap->cmdidx == CMD_lfdo); 4977 4978 qf_jump(qi, 0, errornr, eap->forceit); 4979 } 4980 4981 /* 4982 * ":cnext", ":cnfile", ":cNext" and ":cprevious". 4983 * ":lnext", ":lNext", ":lprevious", ":lnfile", ":lNfile" and ":lpfile". 4984 * Also, used by ":cdo", ":ldo", ":cfdo" and ":lfdo" commands. 4985 */ 4986 void 4987 ex_cnext(exarg_T *eap) 4988 { 4989 qf_info_T *qi = &ql_info; 4990 int errornr; 4991 int dir; 4992 4993 if (is_loclist_cmd(eap->cmdidx)) 4994 { 4995 qi = GET_LOC_LIST(curwin); 4996 if (qi == NULL) 4997 { 4998 emsg(_(e_loclist)); 4999 return; 5000 } 5001 } 5002 5003 if (eap->addr_count > 0 5004 && (eap->cmdidx != CMD_cdo && eap->cmdidx != CMD_ldo 5005 && eap->cmdidx != CMD_cfdo && eap->cmdidx != CMD_lfdo)) 5006 errornr = (int)eap->line2; 5007 else 5008 errornr = 1; 5009 5010 // Depending on the command jump to either next or previous entry/file. 5011 switch (eap->cmdidx) 5012 { 5013 case CMD_cnext: case CMD_lnext: case CMD_cdo: case CMD_ldo: 5014 dir = FORWARD; 5015 break; 5016 case CMD_cprevious: case CMD_lprevious: case CMD_cNext: 5017 case CMD_lNext: 5018 dir = BACKWARD; 5019 break; 5020 case CMD_cnfile: case CMD_lnfile: case CMD_cfdo: case CMD_lfdo: 5021 dir = FORWARD_FILE; 5022 break; 5023 case CMD_cpfile: case CMD_lpfile: case CMD_cNfile: case CMD_lNfile: 5024 dir = BACKWARD_FILE; 5025 break; 5026 default: 5027 dir = FORWARD; 5028 break; 5029 } 5030 5031 qf_jump(qi, dir, errornr, eap->forceit); 5032 } 5033 5034 /* 5035 * ":cfile"/":cgetfile"/":caddfile" commands. 5036 * ":lfile"/":lgetfile"/":laddfile" commands. 5037 */ 5038 void 5039 ex_cfile(exarg_T *eap) 5040 { 5041 char_u *enc = NULL; 5042 win_T *wp = NULL; 5043 qf_info_T *qi = &ql_info; 5044 char_u *au_name = NULL; 5045 int_u save_qfid = 0; // init for gcc 5046 int res; 5047 5048 switch (eap->cmdidx) 5049 { 5050 case CMD_cfile: au_name = (char_u *)"cfile"; break; 5051 case CMD_cgetfile: au_name = (char_u *)"cgetfile"; break; 5052 case CMD_caddfile: au_name = (char_u *)"caddfile"; break; 5053 case CMD_lfile: au_name = (char_u *)"lfile"; break; 5054 case CMD_lgetfile: au_name = (char_u *)"lgetfile"; break; 5055 case CMD_laddfile: au_name = (char_u *)"laddfile"; break; 5056 default: break; 5057 } 5058 if (au_name != NULL) 5059 apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf); 5060 enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; 5061 #ifdef FEAT_BROWSE 5062 if (cmdmod.browse) 5063 { 5064 char_u *browse_file = do_browse(0, (char_u *)_("Error file"), eap->arg, 5065 NULL, NULL, 5066 (char_u *)_(BROWSE_FILTER_ALL_FILES), NULL); 5067 if (browse_file == NULL) 5068 return; 5069 set_string_option_direct((char_u *)"ef", -1, browse_file, OPT_FREE, 0); 5070 vim_free(browse_file); 5071 } 5072 else 5073 #endif 5074 if (*eap->arg != NUL) 5075 set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE, 0); 5076 5077 if (is_loclist_cmd(eap->cmdidx)) 5078 wp = curwin; 5079 5080 incr_quickfix_busy(); 5081 5082 // This function is used by the :cfile, :cgetfile and :caddfile 5083 // commands. 5084 // :cfile always creates a new quickfix list and jumps to the 5085 // first error. 5086 // :cgetfile creates a new quickfix list but doesn't jump to the 5087 // first error. 5088 // :caddfile adds to an existing quickfix list. If there is no 5089 // quickfix list then a new list is created. 5090 res = qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile 5091 && eap->cmdidx != CMD_laddfile), 5092 qf_cmdtitle(*eap->cmdlinep), enc); 5093 if (wp != NULL) 5094 { 5095 qi = GET_LOC_LIST(wp); 5096 if (qi == NULL) 5097 { 5098 decr_quickfix_busy(); 5099 return; 5100 } 5101 } 5102 if (res >= 0) 5103 qf_list_changed(&qi->qf_lists[qi->qf_curlist]); 5104 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 5105 if (au_name != NULL) 5106 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, NULL, FALSE, curbuf); 5107 5108 // Jump to the first error for a new list and if autocmds didn't 5109 // free the list. 5110 if (res > 0 && (eap->cmdidx == CMD_cfile || eap->cmdidx == CMD_lfile) 5111 && qflist_valid(wp, save_qfid)) 5112 // display the first error 5113 qf_jump_first(qi, save_qfid, eap->forceit); 5114 5115 decr_quickfix_busy(); 5116 } 5117 5118 /* 5119 * Return the vimgrep autocmd name. 5120 */ 5121 static char_u * 5122 vgr_get_auname(cmdidx_T cmdidx) 5123 { 5124 switch (cmdidx) 5125 { 5126 case CMD_vimgrep: return (char_u *)"vimgrep"; 5127 case CMD_lvimgrep: return (char_u *)"lvimgrep"; 5128 case CMD_vimgrepadd: return (char_u *)"vimgrepadd"; 5129 case CMD_lvimgrepadd: return (char_u *)"lvimgrepadd"; 5130 case CMD_grep: return (char_u *)"grep"; 5131 case CMD_lgrep: return (char_u *)"lgrep"; 5132 case CMD_grepadd: return (char_u *)"grepadd"; 5133 case CMD_lgrepadd: return (char_u *)"lgrepadd"; 5134 default: return NULL; 5135 } 5136 } 5137 5138 /* 5139 * Initialize the regmatch used by vimgrep for pattern "s". 5140 */ 5141 static void 5142 vgr_init_regmatch(regmmatch_T *regmatch, char_u *s) 5143 { 5144 // Get the search pattern: either white-separated or enclosed in // 5145 regmatch->regprog = NULL; 5146 5147 if (s == NULL || *s == NUL) 5148 { 5149 // Pattern is empty, use last search pattern. 5150 if (last_search_pat() == NULL) 5151 { 5152 emsg(_(e_noprevre)); 5153 return; 5154 } 5155 regmatch->regprog = vim_regcomp(last_search_pat(), RE_MAGIC); 5156 } 5157 else 5158 regmatch->regprog = vim_regcomp(s, RE_MAGIC); 5159 5160 regmatch->rmm_ic = p_ic; 5161 regmatch->rmm_maxcol = 0; 5162 } 5163 5164 /* 5165 * Display a file name when vimgrep is running. 5166 */ 5167 static void 5168 vgr_display_fname(char_u *fname) 5169 { 5170 char_u *p; 5171 5172 msg_start(); 5173 p = msg_strtrunc(fname, TRUE); 5174 if (p == NULL) 5175 msg_outtrans(fname); 5176 else 5177 { 5178 msg_outtrans(p); 5179 vim_free(p); 5180 } 5181 msg_clr_eos(); 5182 msg_didout = FALSE; // overwrite this message 5183 msg_nowait = TRUE; // don't wait for this message 5184 msg_col = 0; 5185 out_flush(); 5186 } 5187 5188 /* 5189 * Load a dummy buffer to search for a pattern using vimgrep. 5190 */ 5191 static buf_T * 5192 vgr_load_dummy_buf( 5193 char_u *fname, 5194 char_u *dirname_start, 5195 char_u *dirname_now) 5196 { 5197 int save_mls; 5198 #if defined(FEAT_SYN_HL) 5199 char_u *save_ei = NULL; 5200 #endif 5201 buf_T *buf; 5202 5203 #if defined(FEAT_SYN_HL) 5204 // Don't do Filetype autocommands to avoid loading syntax and 5205 // indent scripts, a great speed improvement. 5206 save_ei = au_event_disable(",Filetype"); 5207 #endif 5208 // Don't use modelines here, it's useless. 5209 save_mls = p_mls; 5210 p_mls = 0; 5211 5212 // Load file into a buffer, so that 'fileencoding' is detected, 5213 // autocommands applied, etc. 5214 buf = load_dummy_buffer(fname, dirname_start, dirname_now); 5215 5216 p_mls = save_mls; 5217 #if defined(FEAT_SYN_HL) 5218 au_event_restore(save_ei); 5219 #endif 5220 5221 return buf; 5222 } 5223 5224 /* 5225 * Check whether a quickfix/location list valid. Autocmds may remove or change 5226 * a quickfix list when vimgrep is running. If the list is not found, create a 5227 * new list. 5228 */ 5229 static int 5230 vgr_qflist_valid( 5231 win_T *wp, 5232 qf_info_T *qi, 5233 int_u qfid, 5234 char_u *title) 5235 { 5236 // Verify that the quickfix/location list was not freed by an autocmd 5237 if (!qflist_valid(wp, qfid)) 5238 { 5239 if (wp != NULL) 5240 { 5241 // An autocmd has freed the location list. 5242 emsg(_(e_loc_list_changed)); 5243 return FALSE; 5244 } 5245 else 5246 { 5247 // Quickfix list is not found, create a new one. 5248 qf_new_list(qi, title); 5249 return TRUE; 5250 } 5251 } 5252 5253 if (qf_restore_list(qi, qfid) == FAIL) 5254 return FALSE; 5255 5256 return TRUE; 5257 } 5258 5259 /* 5260 * Search for a pattern in all the lines in a buffer and add the matching lines 5261 * to a quickfix list. 5262 */ 5263 static int 5264 vgr_match_buflines( 5265 qf_info_T *qi, 5266 char_u *fname, 5267 buf_T *buf, 5268 regmmatch_T *regmatch, 5269 long *tomatch, 5270 int duplicate_name, 5271 int flags) 5272 { 5273 int found_match = FALSE; 5274 long lnum; 5275 colnr_T col; 5276 5277 for (lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; ++lnum) 5278 { 5279 col = 0; 5280 while (vim_regexec_multi(regmatch, curwin, buf, lnum, 5281 col, NULL, NULL) > 0) 5282 { 5283 // Pass the buffer number so that it gets used even for a 5284 // dummy buffer, unless duplicate_name is set, then the 5285 // buffer will be wiped out below. 5286 if (qf_add_entry(qi, 5287 qi->qf_curlist, 5288 NULL, // dir 5289 fname, 5290 NULL, 5291 duplicate_name ? 0 : buf->b_fnum, 5292 ml_get_buf(buf, 5293 regmatch->startpos[0].lnum + lnum, FALSE), 5294 regmatch->startpos[0].lnum + lnum, 5295 regmatch->startpos[0].col + 1, 5296 FALSE, // vis_col 5297 NULL, // search pattern 5298 0, // nr 5299 0, // type 5300 TRUE // valid 5301 ) == FAIL) 5302 { 5303 got_int = TRUE; 5304 break; 5305 } 5306 found_match = TRUE; 5307 if (--*tomatch == 0) 5308 break; 5309 if ((flags & VGR_GLOBAL) == 0 5310 || regmatch->endpos[0].lnum > 0) 5311 break; 5312 col = regmatch->endpos[0].col 5313 + (col == regmatch->endpos[0].col); 5314 if (col > (colnr_T)STRLEN(ml_get_buf(buf, lnum, FALSE))) 5315 break; 5316 } 5317 line_breakcheck(); 5318 if (got_int) 5319 break; 5320 } 5321 5322 return found_match; 5323 } 5324 5325 /* 5326 * Jump to the first match and update the directory. 5327 */ 5328 static void 5329 vgr_jump_to_match( 5330 qf_info_T *qi, 5331 int forceit, 5332 int *redraw_for_dummy, 5333 buf_T *first_match_buf, 5334 char_u *target_dir) 5335 { 5336 buf_T *buf; 5337 5338 buf = curbuf; 5339 qf_jump(qi, 0, 0, forceit); 5340 if (buf != curbuf) 5341 // If we jumped to another buffer redrawing will already be 5342 // taken care of. 5343 *redraw_for_dummy = FALSE; 5344 5345 // Jump to the directory used after loading the buffer. 5346 if (curbuf == first_match_buf && target_dir != NULL) 5347 { 5348 exarg_T ea; 5349 5350 ea.arg = target_dir; 5351 ea.cmdidx = CMD_lcd; 5352 ex_cd(&ea); 5353 } 5354 } 5355 5356 /* 5357 * ":vimgrep {pattern} file(s)" 5358 * ":vimgrepadd {pattern} file(s)" 5359 * ":lvimgrep {pattern} file(s)" 5360 * ":lvimgrepadd {pattern} file(s)" 5361 */ 5362 void 5363 ex_vimgrep(exarg_T *eap) 5364 { 5365 regmmatch_T regmatch; 5366 int fcount; 5367 char_u **fnames; 5368 char_u *fname; 5369 char_u *title; 5370 char_u *s; 5371 char_u *p; 5372 int fi; 5373 qf_info_T *qi = &ql_info; 5374 qf_list_T *qfl; 5375 int_u save_qfid; 5376 win_T *wp = NULL; 5377 buf_T *buf; 5378 int duplicate_name = FALSE; 5379 int using_dummy; 5380 int redraw_for_dummy = FALSE; 5381 int found_match; 5382 buf_T *first_match_buf = NULL; 5383 time_t seconds = 0; 5384 aco_save_T aco; 5385 int flags = 0; 5386 long tomatch; 5387 char_u *dirname_start = NULL; 5388 char_u *dirname_now = NULL; 5389 char_u *target_dir = NULL; 5390 char_u *au_name = NULL; 5391 5392 au_name = vgr_get_auname(eap->cmdidx); 5393 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, 5394 curbuf->b_fname, TRUE, curbuf)) 5395 { 5396 #ifdef FEAT_EVAL 5397 if (aborting()) 5398 return; 5399 #endif 5400 } 5401 5402 if (is_loclist_cmd(eap->cmdidx)) 5403 { 5404 qi = ll_get_or_alloc_list(curwin); 5405 if (qi == NULL) 5406 return; 5407 wp = curwin; 5408 } 5409 5410 if (eap->addr_count > 0) 5411 tomatch = eap->line2; 5412 else 5413 tomatch = MAXLNUM; 5414 5415 // Get the search pattern: either white-separated or enclosed in // 5416 regmatch.regprog = NULL; 5417 title = vim_strsave(qf_cmdtitle(*eap->cmdlinep)); 5418 p = skip_vimgrep_pat(eap->arg, &s, &flags); 5419 if (p == NULL) 5420 { 5421 emsg(_(e_invalpat)); 5422 goto theend; 5423 } 5424 5425 vgr_init_regmatch(®match, s); 5426 if (regmatch.regprog == NULL) 5427 goto theend; 5428 5429 p = skipwhite(p); 5430 if (*p == NUL) 5431 { 5432 emsg(_("E683: File name missing or invalid pattern")); 5433 goto theend; 5434 } 5435 5436 if ((eap->cmdidx != CMD_grepadd && eap->cmdidx != CMD_lgrepadd 5437 && eap->cmdidx != CMD_vimgrepadd 5438 && eap->cmdidx != CMD_lvimgrepadd) 5439 || qf_stack_empty(qi)) 5440 // make place for a new list 5441 qf_new_list(qi, title != NULL ? title : qf_cmdtitle(*eap->cmdlinep)); 5442 5443 // parse the list of arguments 5444 if (get_arglist_exp(p, &fcount, &fnames, TRUE) == FAIL) 5445 goto theend; 5446 if (fcount == 0) 5447 { 5448 emsg(_(e_nomatch)); 5449 goto theend; 5450 } 5451 5452 dirname_start = alloc_id(MAXPATHL, aid_qf_dirname_start); 5453 dirname_now = alloc_id(MAXPATHL, aid_qf_dirname_now); 5454 if (dirname_start == NULL || dirname_now == NULL) 5455 { 5456 FreeWild(fcount, fnames); 5457 goto theend; 5458 } 5459 5460 // Remember the current directory, because a BufRead autocommand that does 5461 // ":lcd %:p:h" changes the meaning of short path names. 5462 mch_dirname(dirname_start, MAXPATHL); 5463 5464 incr_quickfix_busy(); 5465 5466 // Remember the current quickfix list identifier, so that we can check for 5467 // autocommands changing the current quickfix list. 5468 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 5469 5470 seconds = (time_t)0; 5471 for (fi = 0; fi < fcount && !got_int && tomatch > 0; ++fi) 5472 { 5473 fname = shorten_fname1(fnames[fi]); 5474 if (time(NULL) > seconds) 5475 { 5476 // Display the file name every second or so, show the user we are 5477 // working on it. 5478 seconds = time(NULL); 5479 vgr_display_fname(fname); 5480 } 5481 5482 buf = buflist_findname_exp(fnames[fi]); 5483 if (buf == NULL || buf->b_ml.ml_mfp == NULL) 5484 { 5485 // Remember that a buffer with this name already exists. 5486 duplicate_name = (buf != NULL); 5487 using_dummy = TRUE; 5488 redraw_for_dummy = TRUE; 5489 5490 buf = vgr_load_dummy_buf(fname, dirname_start, dirname_now); 5491 } 5492 else 5493 // Use existing, loaded buffer. 5494 using_dummy = FALSE; 5495 5496 // Check whether the quickfix list is still valid. When loading a 5497 // buffer above, autocommands might have changed the quickfix list. 5498 if (!vgr_qflist_valid(wp, qi, save_qfid, qf_cmdtitle(*eap->cmdlinep))) 5499 { 5500 FreeWild(fcount, fnames); 5501 decr_quickfix_busy(); 5502 goto theend; 5503 } 5504 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 5505 5506 if (buf == NULL) 5507 { 5508 if (!got_int) 5509 smsg(_("Cannot open file \"%s\""), fname); 5510 } 5511 else 5512 { 5513 // Try for a match in all lines of the buffer. 5514 // For ":1vimgrep" look for first match only. 5515 found_match = vgr_match_buflines(qi, fname, buf, ®match, 5516 &tomatch, duplicate_name, flags); 5517 5518 if (using_dummy) 5519 { 5520 if (found_match && first_match_buf == NULL) 5521 first_match_buf = buf; 5522 if (duplicate_name) 5523 { 5524 // Never keep a dummy buffer if there is another buffer 5525 // with the same name. 5526 wipe_dummy_buffer(buf, dirname_start); 5527 buf = NULL; 5528 } 5529 else if (!cmdmod.hide 5530 || buf->b_p_bh[0] == 'u' // "unload" 5531 || buf->b_p_bh[0] == 'w' // "wipe" 5532 || buf->b_p_bh[0] == 'd') // "delete" 5533 { 5534 // When no match was found we don't need to remember the 5535 // buffer, wipe it out. If there was a match and it 5536 // wasn't the first one or we won't jump there: only 5537 // unload the buffer. 5538 // Ignore 'hidden' here, because it may lead to having too 5539 // many swap files. 5540 if (!found_match) 5541 { 5542 wipe_dummy_buffer(buf, dirname_start); 5543 buf = NULL; 5544 } 5545 else if (buf != first_match_buf || (flags & VGR_NOJUMP)) 5546 { 5547 unload_dummy_buffer(buf, dirname_start); 5548 // Keeping the buffer, remove the dummy flag. 5549 buf->b_flags &= ~BF_DUMMY; 5550 buf = NULL; 5551 } 5552 } 5553 5554 if (buf != NULL) 5555 { 5556 // Keeping the buffer, remove the dummy flag. 5557 buf->b_flags &= ~BF_DUMMY; 5558 5559 // If the buffer is still loaded we need to use the 5560 // directory we jumped to below. 5561 if (buf == first_match_buf 5562 && target_dir == NULL 5563 && STRCMP(dirname_start, dirname_now) != 0) 5564 target_dir = vim_strsave(dirname_now); 5565 5566 // The buffer is still loaded, the Filetype autocommands 5567 // need to be done now, in that buffer. And the modelines 5568 // need to be done (again). But not the window-local 5569 // options! 5570 aucmd_prepbuf(&aco, buf); 5571 #if defined(FEAT_SYN_HL) 5572 apply_autocmds(EVENT_FILETYPE, buf->b_p_ft, 5573 buf->b_fname, TRUE, buf); 5574 #endif 5575 do_modelines(OPT_NOWIN); 5576 aucmd_restbuf(&aco); 5577 } 5578 } 5579 } 5580 } 5581 5582 FreeWild(fcount, fnames); 5583 5584 qfl = &qi->qf_lists[qi->qf_curlist]; 5585 qfl->qf_nonevalid = FALSE; 5586 qfl->qf_ptr = qfl->qf_start; 5587 qfl->qf_index = 1; 5588 qf_list_changed(qfl); 5589 5590 qf_update_buffer(qi, NULL); 5591 5592 if (au_name != NULL) 5593 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, 5594 curbuf->b_fname, TRUE, curbuf); 5595 // The QuickFixCmdPost autocmd may free the quickfix list. Check the list 5596 // is still valid. 5597 if (!qflist_valid(wp, save_qfid) 5598 || qf_restore_list(qi, save_qfid) == FAIL) 5599 { 5600 decr_quickfix_busy(); 5601 goto theend; 5602 } 5603 5604 // Jump to first match. 5605 if (!qf_list_empty(qi, qi->qf_curlist)) 5606 { 5607 if ((flags & VGR_NOJUMP) == 0) 5608 vgr_jump_to_match(qi, eap->forceit, &redraw_for_dummy, 5609 first_match_buf, target_dir); 5610 } 5611 else 5612 semsg(_(e_nomatch2), s); 5613 5614 decr_quickfix_busy(); 5615 5616 // If we loaded a dummy buffer into the current window, the autocommands 5617 // may have messed up things, need to redraw and recompute folds. 5618 if (redraw_for_dummy) 5619 { 5620 #ifdef FEAT_FOLDING 5621 foldUpdateAll(curwin); 5622 #else 5623 redraw_later(NOT_VALID); 5624 #endif 5625 } 5626 5627 theend: 5628 vim_free(title); 5629 vim_free(dirname_now); 5630 vim_free(dirname_start); 5631 vim_free(target_dir); 5632 vim_regfree(regmatch.regprog); 5633 } 5634 5635 /* 5636 * Restore current working directory to "dirname_start" if they differ, taking 5637 * into account whether it is set locally or globally. 5638 */ 5639 static void 5640 restore_start_dir(char_u *dirname_start) 5641 { 5642 char_u *dirname_now = alloc(MAXPATHL); 5643 5644 if (NULL != dirname_now) 5645 { 5646 mch_dirname(dirname_now, MAXPATHL); 5647 if (STRCMP(dirname_start, dirname_now) != 0) 5648 { 5649 // If the directory has changed, change it back by building up an 5650 // appropriate ex command and executing it. 5651 exarg_T ea; 5652 5653 ea.arg = dirname_start; 5654 ea.cmdidx = (curwin->w_localdir == NULL) ? CMD_cd : CMD_lcd; 5655 ex_cd(&ea); 5656 } 5657 vim_free(dirname_now); 5658 } 5659 } 5660 5661 /* 5662 * Load file "fname" into a dummy buffer and return the buffer pointer, 5663 * placing the directory resulting from the buffer load into the 5664 * "resulting_dir" pointer. "resulting_dir" must be allocated by the caller 5665 * prior to calling this function. Restores directory to "dirname_start" prior 5666 * to returning, if autocmds or the 'autochdir' option have changed it. 5667 * 5668 * If creating the dummy buffer does not fail, must call unload_dummy_buffer() 5669 * or wipe_dummy_buffer() later! 5670 * 5671 * Returns NULL if it fails. 5672 */ 5673 static buf_T * 5674 load_dummy_buffer( 5675 char_u *fname, 5676 char_u *dirname_start, // in: old directory 5677 char_u *resulting_dir) // out: new directory 5678 { 5679 buf_T *newbuf; 5680 bufref_T newbufref; 5681 bufref_T newbuf_to_wipe; 5682 int failed = TRUE; 5683 aco_save_T aco; 5684 int readfile_result; 5685 5686 // Allocate a buffer without putting it in the buffer list. 5687 newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); 5688 if (newbuf == NULL) 5689 return NULL; 5690 set_bufref(&newbufref, newbuf); 5691 5692 // Init the options. 5693 buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP); 5694 5695 // need to open the memfile before putting the buffer in a window 5696 if (ml_open(newbuf) == OK) 5697 { 5698 // Make sure this buffer isn't wiped out by autocommands. 5699 ++newbuf->b_locked; 5700 5701 // set curwin/curbuf to buf and save a few things 5702 aucmd_prepbuf(&aco, newbuf); 5703 5704 // Need to set the filename for autocommands. 5705 (void)setfname(curbuf, fname, NULL, FALSE); 5706 5707 // Create swap file now to avoid the ATTENTION message. 5708 check_need_swap(TRUE); 5709 5710 // Remove the "dummy" flag, otherwise autocommands may not 5711 // work. 5712 curbuf->b_flags &= ~BF_DUMMY; 5713 5714 newbuf_to_wipe.br_buf = NULL; 5715 readfile_result = readfile(fname, NULL, 5716 (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, 5717 NULL, READ_NEW | READ_DUMMY); 5718 --newbuf->b_locked; 5719 if (readfile_result == OK 5720 && !got_int 5721 && !(curbuf->b_flags & BF_NEW)) 5722 { 5723 failed = FALSE; 5724 if (curbuf != newbuf) 5725 { 5726 // Bloody autocommands changed the buffer! Can happen when 5727 // using netrw and editing a remote file. Use the current 5728 // buffer instead, delete the dummy one after restoring the 5729 // window stuff. 5730 set_bufref(&newbuf_to_wipe, newbuf); 5731 newbuf = curbuf; 5732 } 5733 } 5734 5735 // restore curwin/curbuf and a few other things 5736 aucmd_restbuf(&aco); 5737 if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) 5738 wipe_buffer(newbuf_to_wipe.br_buf, FALSE); 5739 5740 // Add back the "dummy" flag, otherwise buflist_findname_stat() won't 5741 // skip it. 5742 newbuf->b_flags |= BF_DUMMY; 5743 } 5744 5745 // When autocommands/'autochdir' option changed directory: go back. 5746 // Let the caller know what the resulting dir was first, in case it is 5747 // important. 5748 mch_dirname(resulting_dir, MAXPATHL); 5749 restore_start_dir(dirname_start); 5750 5751 if (!bufref_valid(&newbufref)) 5752 return NULL; 5753 if (failed) 5754 { 5755 wipe_dummy_buffer(newbuf, dirname_start); 5756 return NULL; 5757 } 5758 return newbuf; 5759 } 5760 5761 /* 5762 * Wipe out the dummy buffer that load_dummy_buffer() created. Restores 5763 * directory to "dirname_start" prior to returning, if autocmds or the 5764 * 'autochdir' option have changed it. 5765 */ 5766 static void 5767 wipe_dummy_buffer(buf_T *buf, char_u *dirname_start) 5768 { 5769 if (curbuf != buf) // safety check 5770 { 5771 #if defined(FEAT_EVAL) 5772 cleanup_T cs; 5773 5774 // Reset the error/interrupt/exception state here so that aborting() 5775 // returns FALSE when wiping out the buffer. Otherwise it doesn't 5776 // work when got_int is set. 5777 enter_cleanup(&cs); 5778 #endif 5779 5780 wipe_buffer(buf, FALSE); 5781 5782 #if defined(FEAT_EVAL) 5783 // Restore the error/interrupt/exception state if not discarded by a 5784 // new aborting error, interrupt, or uncaught exception. 5785 leave_cleanup(&cs); 5786 #endif 5787 // When autocommands/'autochdir' option changed directory: go back. 5788 restore_start_dir(dirname_start); 5789 } 5790 } 5791 5792 /* 5793 * Unload the dummy buffer that load_dummy_buffer() created. Restores 5794 * directory to "dirname_start" prior to returning, if autocmds or the 5795 * 'autochdir' option have changed it. 5796 */ 5797 static void 5798 unload_dummy_buffer(buf_T *buf, char_u *dirname_start) 5799 { 5800 if (curbuf != buf) // safety check 5801 { 5802 close_buffer(NULL, buf, DOBUF_UNLOAD, FALSE); 5803 5804 // When autocommands/'autochdir' option changed directory: go back. 5805 restore_start_dir(dirname_start); 5806 } 5807 } 5808 5809 #if defined(FEAT_EVAL) || defined(PROTO) 5810 /* 5811 * Add each quickfix error to list "list" as a dictionary. 5812 * If qf_idx is -1, use the current list. Otherwise, use the specified list. 5813 */ 5814 int 5815 get_errorlist(qf_info_T *qi_arg, win_T *wp, int qf_idx, list_T *list) 5816 { 5817 qf_info_T *qi = qi_arg; 5818 dict_T *dict; 5819 char_u buf[2]; 5820 qfline_T *qfp; 5821 int i; 5822 int bufnum; 5823 5824 if (qi == NULL) 5825 { 5826 qi = &ql_info; 5827 if (wp != NULL) 5828 { 5829 qi = GET_LOC_LIST(wp); 5830 if (qi == NULL) 5831 return FAIL; 5832 } 5833 } 5834 5835 if (qf_idx == INVALID_QFIDX) 5836 qf_idx = qi->qf_curlist; 5837 5838 if (qf_idx >= qi->qf_listcount || qf_list_empty(qi, qf_idx)) 5839 return FAIL; 5840 5841 qfp = qi->qf_lists[qf_idx].qf_start; 5842 for (i = 1; !got_int && i <= qi->qf_lists[qf_idx].qf_count; ++i) 5843 { 5844 // Handle entries with a non-existing buffer number. 5845 bufnum = qfp->qf_fnum; 5846 if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) 5847 bufnum = 0; 5848 5849 if ((dict = dict_alloc()) == NULL) 5850 return FAIL; 5851 if (list_append_dict(list, dict) == FAIL) 5852 return FAIL; 5853 5854 buf[0] = qfp->qf_type; 5855 buf[1] = NUL; 5856 if ( dict_add_number(dict, "bufnr", (long)bufnum) == FAIL 5857 || dict_add_number(dict, "lnum", (long)qfp->qf_lnum) == FAIL 5858 || dict_add_number(dict, "col", (long)qfp->qf_col) == FAIL 5859 || dict_add_number(dict, "vcol", (long)qfp->qf_viscol) == FAIL 5860 || dict_add_number(dict, "nr", (long)qfp->qf_nr) == FAIL 5861 || dict_add_string(dict, "module", qfp->qf_module) == FAIL 5862 || dict_add_string(dict, "pattern", qfp->qf_pattern) == FAIL 5863 || dict_add_string(dict, "text", qfp->qf_text) == FAIL 5864 || dict_add_string(dict, "type", buf) == FAIL 5865 || dict_add_number(dict, "valid", (long)qfp->qf_valid) == FAIL) 5866 return FAIL; 5867 5868 qfp = qfp->qf_next; 5869 if (qfp == NULL) 5870 break; 5871 } 5872 return OK; 5873 } 5874 5875 // Flags used by getqflist()/getloclist() to determine which fields to return. 5876 enum { 5877 QF_GETLIST_NONE = 0x0, 5878 QF_GETLIST_TITLE = 0x1, 5879 QF_GETLIST_ITEMS = 0x2, 5880 QF_GETLIST_NR = 0x4, 5881 QF_GETLIST_WINID = 0x8, 5882 QF_GETLIST_CONTEXT = 0x10, 5883 QF_GETLIST_ID = 0x20, 5884 QF_GETLIST_IDX = 0x40, 5885 QF_GETLIST_SIZE = 0x80, 5886 QF_GETLIST_TICK = 0x100, 5887 QF_GETLIST_FILEWINID = 0x200, 5888 QF_GETLIST_ALL = 0x3FF, 5889 }; 5890 5891 /* 5892 * Parse text from 'di' and return the quickfix list items. 5893 * Existing quickfix lists are not modified. 5894 */ 5895 static int 5896 qf_get_list_from_lines(dict_T *what, dictitem_T *di, dict_T *retdict) 5897 { 5898 int status = FAIL; 5899 qf_info_T *qi; 5900 char_u *errorformat = p_efm; 5901 dictitem_T *efm_di; 5902 list_T *l; 5903 5904 // Only a List value is supported 5905 if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL) 5906 { 5907 // If errorformat is supplied then use it, otherwise use the 'efm' 5908 // option setting 5909 if ((efm_di = dict_find(what, (char_u *)"efm", -1)) != NULL) 5910 { 5911 if (efm_di->di_tv.v_type != VAR_STRING || 5912 efm_di->di_tv.vval.v_string == NULL) 5913 return FAIL; 5914 errorformat = efm_di->di_tv.vval.v_string; 5915 } 5916 5917 l = list_alloc(); 5918 if (l == NULL) 5919 return FAIL; 5920 5921 qi = qf_alloc_stack(QFLT_INTERNAL); 5922 if (qi != NULL) 5923 { 5924 if (qf_init_ext(qi, 0, NULL, NULL, &di->di_tv, errorformat, 5925 TRUE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) 5926 { 5927 (void)get_errorlist(qi, NULL, 0, l); 5928 qf_free(&qi->qf_lists[0]); 5929 } 5930 free(qi); 5931 } 5932 dict_add_list(retdict, "items", l); 5933 status = OK; 5934 } 5935 5936 return status; 5937 } 5938 5939 /* 5940 * Return the quickfix/location list window identifier in the current tabpage. 5941 */ 5942 static int 5943 qf_winid(qf_info_T *qi) 5944 { 5945 win_T *win; 5946 5947 // The quickfix window can be opened even if the quickfix list is not set 5948 // using ":copen". This is not true for location lists. 5949 if (qi == NULL) 5950 return 0; 5951 win = qf_find_win(qi); 5952 if (win != NULL) 5953 return win->w_id; 5954 return 0; 5955 } 5956 5957 /* 5958 * Convert the keys in 'what' to quickfix list property flags. 5959 */ 5960 static int 5961 qf_getprop_keys2flags(dict_T *what, int loclist) 5962 { 5963 int flags = QF_GETLIST_NONE; 5964 5965 if (dict_find(what, (char_u *)"all", -1) != NULL) 5966 { 5967 flags |= QF_GETLIST_ALL; 5968 if (!loclist) 5969 // File window ID is applicable only to location list windows 5970 flags &= ~ QF_GETLIST_FILEWINID; 5971 } 5972 5973 if (dict_find(what, (char_u *)"title", -1) != NULL) 5974 flags |= QF_GETLIST_TITLE; 5975 5976 if (dict_find(what, (char_u *)"nr", -1) != NULL) 5977 flags |= QF_GETLIST_NR; 5978 5979 if (dict_find(what, (char_u *)"winid", -1) != NULL) 5980 flags |= QF_GETLIST_WINID; 5981 5982 if (dict_find(what, (char_u *)"context", -1) != NULL) 5983 flags |= QF_GETLIST_CONTEXT; 5984 5985 if (dict_find(what, (char_u *)"id", -1) != NULL) 5986 flags |= QF_GETLIST_ID; 5987 5988 if (dict_find(what, (char_u *)"items", -1) != NULL) 5989 flags |= QF_GETLIST_ITEMS; 5990 5991 if (dict_find(what, (char_u *)"idx", -1) != NULL) 5992 flags |= QF_GETLIST_IDX; 5993 5994 if (dict_find(what, (char_u *)"size", -1) != NULL) 5995 flags |= QF_GETLIST_SIZE; 5996 5997 if (dict_find(what, (char_u *)"changedtick", -1) != NULL) 5998 flags |= QF_GETLIST_TICK; 5999 6000 if (loclist && dict_find(what, (char_u *)"filewinid", -1) != NULL) 6001 flags |= QF_GETLIST_FILEWINID; 6002 6003 return flags; 6004 } 6005 6006 /* 6007 * Return the quickfix list index based on 'nr' or 'id' in 'what'. 6008 * If 'nr' and 'id' are not present in 'what' then return the current 6009 * quickfix list index. 6010 * If 'nr' is zero then return the current quickfix list index. 6011 * If 'nr' is '$' then return the last quickfix list index. 6012 * If 'id' is present then return the index of the quickfix list with that id. 6013 * If 'id' is zero then return the quickfix list index specified by 'nr'. 6014 * Return -1, if quickfix list is not present or if the stack is empty. 6015 */ 6016 static int 6017 qf_getprop_qfidx(qf_info_T *qi, dict_T *what) 6018 { 6019 int qf_idx; 6020 dictitem_T *di; 6021 6022 qf_idx = qi->qf_curlist; // default is the current list 6023 if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) 6024 { 6025 // Use the specified quickfix/location list 6026 if (di->di_tv.v_type == VAR_NUMBER) 6027 { 6028 // for zero use the current list 6029 if (di->di_tv.vval.v_number != 0) 6030 { 6031 qf_idx = di->di_tv.vval.v_number - 1; 6032 if (qf_idx < 0 || qf_idx >= qi->qf_listcount) 6033 qf_idx = INVALID_QFIDX; 6034 } 6035 } 6036 else if (di->di_tv.v_type == VAR_STRING 6037 && di->di_tv.vval.v_string != NULL 6038 && STRCMP(di->di_tv.vval.v_string, "$") == 0) 6039 // Get the last quickfix list number 6040 qf_idx = qi->qf_listcount - 1; 6041 else 6042 qf_idx = INVALID_QFIDX; 6043 } 6044 6045 if ((di = dict_find(what, (char_u *)"id", -1)) != NULL) 6046 { 6047 // Look for a list with the specified id 6048 if (di->di_tv.v_type == VAR_NUMBER) 6049 { 6050 // For zero, use the current list or the list specified by 'nr' 6051 if (di->di_tv.vval.v_number != 0) 6052 qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); 6053 } 6054 else 6055 qf_idx = INVALID_QFIDX; 6056 } 6057 6058 return qf_idx; 6059 } 6060 6061 /* 6062 * Return default values for quickfix list properties in retdict. 6063 */ 6064 static int 6065 qf_getprop_defaults(qf_info_T *qi, int flags, int locstack, dict_T *retdict) 6066 { 6067 int status = OK; 6068 6069 if (flags & QF_GETLIST_TITLE) 6070 status = dict_add_string(retdict, "title", (char_u *)""); 6071 if ((status == OK) && (flags & QF_GETLIST_ITEMS)) 6072 { 6073 list_T *l = list_alloc(); 6074 if (l != NULL) 6075 status = dict_add_list(retdict, "items", l); 6076 else 6077 status = FAIL; 6078 } 6079 if ((status == OK) && (flags & QF_GETLIST_NR)) 6080 status = dict_add_number(retdict, "nr", 0); 6081 if ((status == OK) && (flags & QF_GETLIST_WINID)) 6082 status = dict_add_number(retdict, "winid", qf_winid(qi)); 6083 if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) 6084 status = dict_add_string(retdict, "context", (char_u *)""); 6085 if ((status == OK) && (flags & QF_GETLIST_ID)) 6086 status = dict_add_number(retdict, "id", 0); 6087 if ((status == OK) && (flags & QF_GETLIST_IDX)) 6088 status = dict_add_number(retdict, "idx", 0); 6089 if ((status == OK) && (flags & QF_GETLIST_SIZE)) 6090 status = dict_add_number(retdict, "size", 0); 6091 if ((status == OK) && (flags & QF_GETLIST_TICK)) 6092 status = dict_add_number(retdict, "changedtick", 0); 6093 if ((status == OK) && locstack && (flags & QF_GETLIST_FILEWINID)) 6094 status = dict_add_number(retdict, "filewinid", 0); 6095 6096 return status; 6097 } 6098 6099 /* 6100 * Return the quickfix list title as 'title' in retdict 6101 */ 6102 static int 6103 qf_getprop_title(qf_list_T *qfl, dict_T *retdict) 6104 { 6105 return dict_add_string(retdict, "title", qfl->qf_title); 6106 } 6107 6108 /* 6109 * Returns the identifier of the window used to display files from a location 6110 * list. If there is no associated window, then returns 0. Useful only when 6111 * called from a location list window. 6112 */ 6113 static int 6114 qf_getprop_filewinid(win_T *wp, qf_info_T *qi, dict_T *retdict) 6115 { 6116 int winid = 0; 6117 6118 if (wp != NULL && IS_LL_WINDOW(wp)) 6119 { 6120 win_T *ll_wp = qf_find_win_with_loclist(qi); 6121 if (ll_wp != NULL) 6122 winid = ll_wp->w_id; 6123 } 6124 6125 return dict_add_number(retdict, "filewinid", winid); 6126 } 6127 6128 /* 6129 * Return the quickfix list items/entries as 'items' in retdict 6130 */ 6131 static int 6132 qf_getprop_items(qf_info_T *qi, int qf_idx, dict_T *retdict) 6133 { 6134 int status = OK; 6135 list_T *l = list_alloc(); 6136 if (l != NULL) 6137 { 6138 (void)get_errorlist(qi, NULL, qf_idx, l); 6139 dict_add_list(retdict, "items", l); 6140 } 6141 else 6142 status = FAIL; 6143 6144 return status; 6145 } 6146 6147 /* 6148 * Return the quickfix list context (if any) as 'context' in retdict. 6149 */ 6150 static int 6151 qf_getprop_ctx(qf_list_T *qfl, dict_T *retdict) 6152 { 6153 int status; 6154 dictitem_T *di; 6155 6156 if (qfl->qf_ctx != NULL) 6157 { 6158 di = dictitem_alloc((char_u *)"context"); 6159 if (di != NULL) 6160 { 6161 copy_tv(qfl->qf_ctx, &di->di_tv); 6162 status = dict_add(retdict, di); 6163 if (status == FAIL) 6164 dictitem_free(di); 6165 } 6166 else 6167 status = FAIL; 6168 } 6169 else 6170 status = dict_add_string(retdict, "context", (char_u *)""); 6171 6172 return status; 6173 } 6174 6175 /* 6176 * Return the current quickfix list index as 'idx' in retdict 6177 */ 6178 static int 6179 qf_getprop_idx(qf_info_T *qi, int qf_idx, dict_T *retdict) 6180 { 6181 int curidx = qi->qf_lists[qf_idx].qf_index; 6182 if (qf_list_empty(qi, qf_idx)) 6183 // For empty lists, current index is set to 0 6184 curidx = 0; 6185 return dict_add_number(retdict, "idx", curidx); 6186 } 6187 6188 /* 6189 * Return quickfix/location list details (title) as a 6190 * dictionary. 'what' contains the details to return. If 'list_idx' is -1, 6191 * then current list is used. Otherwise the specified list is used. 6192 */ 6193 int 6194 qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict) 6195 { 6196 qf_info_T *qi = &ql_info; 6197 qf_list_T *qfl; 6198 int status = OK; 6199 int qf_idx = INVALID_QFIDX; 6200 dictitem_T *di; 6201 int flags = QF_GETLIST_NONE; 6202 6203 if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) 6204 return qf_get_list_from_lines(what, di, retdict); 6205 6206 if (wp != NULL) 6207 qi = GET_LOC_LIST(wp); 6208 6209 flags = qf_getprop_keys2flags(what, (wp != NULL)); 6210 6211 if (!qf_stack_empty(qi)) 6212 qf_idx = qf_getprop_qfidx(qi, what); 6213 6214 // List is not present or is empty 6215 if (qf_stack_empty(qi) || qf_idx == INVALID_QFIDX) 6216 return qf_getprop_defaults(qi, flags, wp != NULL, retdict); 6217 6218 qfl = &qi->qf_lists[qf_idx]; 6219 6220 if (flags & QF_GETLIST_TITLE) 6221 status = qf_getprop_title(qfl, retdict); 6222 if ((status == OK) && (flags & QF_GETLIST_NR)) 6223 status = dict_add_number(retdict, "nr", qf_idx + 1); 6224 if ((status == OK) && (flags & QF_GETLIST_WINID)) 6225 status = dict_add_number(retdict, "winid", qf_winid(qi)); 6226 if ((status == OK) && (flags & QF_GETLIST_ITEMS)) 6227 status = qf_getprop_items(qi, qf_idx, retdict); 6228 if ((status == OK) && (flags & QF_GETLIST_CONTEXT)) 6229 status = qf_getprop_ctx(qfl, retdict); 6230 if ((status == OK) && (flags & QF_GETLIST_ID)) 6231 status = dict_add_number(retdict, "id", qfl->qf_id); 6232 if ((status == OK) && (flags & QF_GETLIST_IDX)) 6233 status = qf_getprop_idx(qi, qf_idx, retdict); 6234 if ((status == OK) && (flags & QF_GETLIST_SIZE)) 6235 status = dict_add_number(retdict, "size", qfl->qf_count); 6236 if ((status == OK) && (flags & QF_GETLIST_TICK)) 6237 status = dict_add_number(retdict, "changedtick", qfl->qf_changedtick); 6238 if ((status == OK) && (wp != NULL) && (flags & QF_GETLIST_FILEWINID)) 6239 status = qf_getprop_filewinid(wp, qi, retdict); 6240 6241 return status; 6242 } 6243 6244 /* 6245 * Add a new quickfix entry to list at 'qf_idx' in the stack 'qi' from the 6246 * items in the dict 'd'. If it is a valid error entry, then set 'valid_entry' 6247 * to TRUE. 6248 */ 6249 static int 6250 qf_add_entry_from_dict( 6251 qf_info_T *qi, 6252 int qf_idx, 6253 dict_T *d, 6254 int first_entry, 6255 int *valid_entry) 6256 { 6257 static int did_bufnr_emsg; 6258 char_u *filename, *module, *pattern, *text, *type; 6259 int bufnum, valid, status, col, vcol, nr; 6260 long lnum; 6261 6262 if (first_entry) 6263 did_bufnr_emsg = FALSE; 6264 6265 filename = dict_get_string(d, (char_u *)"filename", TRUE); 6266 module = dict_get_string(d, (char_u *)"module", TRUE); 6267 bufnum = (int)dict_get_number(d, (char_u *)"bufnr"); 6268 lnum = (int)dict_get_number(d, (char_u *)"lnum"); 6269 col = (int)dict_get_number(d, (char_u *)"col"); 6270 vcol = (int)dict_get_number(d, (char_u *)"vcol"); 6271 nr = (int)dict_get_number(d, (char_u *)"nr"); 6272 type = dict_get_string(d, (char_u *)"type", TRUE); 6273 pattern = dict_get_string(d, (char_u *)"pattern", TRUE); 6274 text = dict_get_string(d, (char_u *)"text", TRUE); 6275 if (text == NULL) 6276 text = vim_strsave((char_u *)""); 6277 6278 valid = TRUE; 6279 if ((filename == NULL && bufnum == 0) || (lnum == 0 && pattern == NULL)) 6280 valid = FALSE; 6281 6282 // Mark entries with non-existing buffer number as not valid. Give the 6283 // error message only once. 6284 if (bufnum != 0 && (buflist_findnr(bufnum) == NULL)) 6285 { 6286 if (!did_bufnr_emsg) 6287 { 6288 did_bufnr_emsg = TRUE; 6289 semsg(_("E92: Buffer %d not found"), bufnum); 6290 } 6291 valid = FALSE; 6292 bufnum = 0; 6293 } 6294 6295 // If the 'valid' field is present it overrules the detected value. 6296 if ((dict_find(d, (char_u *)"valid", -1)) != NULL) 6297 valid = (int)dict_get_number(d, (char_u *)"valid"); 6298 6299 status = qf_add_entry(qi, 6300 qf_idx, 6301 NULL, // dir 6302 filename, 6303 module, 6304 bufnum, 6305 text, 6306 lnum, 6307 col, 6308 vcol, // vis_col 6309 pattern, // search pattern 6310 nr, 6311 type == NULL ? NUL : *type, 6312 valid); 6313 6314 vim_free(filename); 6315 vim_free(module); 6316 vim_free(pattern); 6317 vim_free(text); 6318 vim_free(type); 6319 6320 if (valid) 6321 *valid_entry = TRUE; 6322 6323 return status; 6324 } 6325 6326 /* 6327 * Add list of entries to quickfix/location list. Each list entry is 6328 * a dictionary with item information. 6329 */ 6330 static int 6331 qf_add_entries( 6332 qf_info_T *qi, 6333 int qf_idx, 6334 list_T *list, 6335 char_u *title, 6336 int action) 6337 { 6338 qf_list_T *qfl = &qi->qf_lists[qf_idx]; 6339 listitem_T *li; 6340 dict_T *d; 6341 qfline_T *old_last = NULL; 6342 int retval = OK; 6343 int valid_entry = FALSE; 6344 6345 if (action == ' ' || qf_idx == qi->qf_listcount) 6346 { 6347 // make place for a new list 6348 qf_new_list(qi, title); 6349 qf_idx = qi->qf_curlist; 6350 qfl = &qi->qf_lists[qf_idx]; 6351 } 6352 else if (action == 'a' && !qf_list_empty(qi, qf_idx)) 6353 // Adding to existing list, use last entry. 6354 old_last = qfl->qf_last; 6355 else if (action == 'r') 6356 { 6357 qf_free_items(qfl); 6358 qf_store_title(qfl, title); 6359 } 6360 6361 for (li = list->lv_first; li != NULL; li = li->li_next) 6362 { 6363 if (li->li_tv.v_type != VAR_DICT) 6364 continue; // Skip non-dict items 6365 6366 d = li->li_tv.vval.v_dict; 6367 if (d == NULL) 6368 continue; 6369 6370 retval = qf_add_entry_from_dict(qi, qf_idx, d, li == list->lv_first, 6371 &valid_entry); 6372 if (retval == FAIL) 6373 break; 6374 } 6375 6376 // Check if any valid error entries are added to the list. 6377 if (valid_entry) 6378 qfl->qf_nonevalid = FALSE; 6379 else if (qfl->qf_index == 0) 6380 // no valid entry 6381 qfl->qf_nonevalid = TRUE; 6382 6383 // If not appending to the list, set the current error to the first entry 6384 if (action != 'a') 6385 qfl->qf_ptr = qfl->qf_start; 6386 6387 // Update the current error index if not appending to the list or if the 6388 // list was empty before and it is not empty now. 6389 if ((action != 'a' || qfl->qf_index == 0) && !qf_list_empty(qi, qf_idx)) 6390 qfl->qf_index = 1; 6391 6392 // Don't update the cursor in quickfix window when appending entries 6393 qf_update_buffer(qi, old_last); 6394 6395 return retval; 6396 } 6397 6398 /* 6399 * Get the quickfix list index from 'nr' or 'id' 6400 */ 6401 static int 6402 qf_setprop_get_qfidx( 6403 qf_info_T *qi, 6404 dict_T *what, 6405 int action, 6406 int *newlist) 6407 { 6408 dictitem_T *di; 6409 int qf_idx = qi->qf_curlist; // default is the current list 6410 6411 if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) 6412 { 6413 // Use the specified quickfix/location list 6414 if (di->di_tv.v_type == VAR_NUMBER) 6415 { 6416 // for zero use the current list 6417 if (di->di_tv.vval.v_number != 0) 6418 qf_idx = di->di_tv.vval.v_number - 1; 6419 6420 if ((action == ' ' || action == 'a') && qf_idx == qi->qf_listcount) 6421 { 6422 // When creating a new list, accept qf_idx pointing to the next 6423 // non-available list and add the new list at the end of the 6424 // stack. 6425 *newlist = TRUE; 6426 qf_idx = qf_stack_empty(qi) ? 0 : qi->qf_listcount - 1; 6427 } 6428 else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) 6429 return INVALID_QFIDX; 6430 else if (action != ' ') 6431 *newlist = FALSE; // use the specified list 6432 } 6433 else if (di->di_tv.v_type == VAR_STRING 6434 && di->di_tv.vval.v_string != NULL 6435 && STRCMP(di->di_tv.vval.v_string, "$") == 0) 6436 { 6437 if (!qf_stack_empty(qi)) 6438 qf_idx = qi->qf_listcount - 1; 6439 else if (*newlist) 6440 qf_idx = 0; 6441 else 6442 return INVALID_QFIDX; 6443 } 6444 else 6445 return INVALID_QFIDX; 6446 } 6447 6448 if (!*newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL) 6449 { 6450 // Use the quickfix/location list with the specified id 6451 if (di->di_tv.v_type != VAR_NUMBER) 6452 return INVALID_QFIDX; 6453 6454 return qf_id2nr(qi, di->di_tv.vval.v_number); 6455 } 6456 6457 return qf_idx; 6458 } 6459 6460 /* 6461 * Set the quickfix list title. 6462 */ 6463 static int 6464 qf_setprop_title(qf_info_T *qi, int qf_idx, dict_T *what, dictitem_T *di) 6465 { 6466 qf_list_T *qfl = &qi->qf_lists[qf_idx]; 6467 6468 if (di->di_tv.v_type != VAR_STRING) 6469 return FAIL; 6470 6471 vim_free(qfl->qf_title); 6472 qfl->qf_title = dict_get_string(what, (char_u *)"title", TRUE); 6473 if (qf_idx == qi->qf_curlist) 6474 qf_update_win_titlevar(qi); 6475 6476 return OK; 6477 } 6478 6479 /* 6480 * Set quickfix list items/entries. 6481 */ 6482 static int 6483 qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action) 6484 { 6485 int retval = FAIL; 6486 char_u *title_save; 6487 6488 if (di->di_tv.v_type != VAR_LIST) 6489 return FAIL; 6490 6491 title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title); 6492 retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list, 6493 title_save, action == ' ' ? 'a' : action); 6494 vim_free(title_save); 6495 6496 return retval; 6497 } 6498 6499 /* 6500 * Set quickfix list items/entries from a list of lines. 6501 */ 6502 static int 6503 qf_setprop_items_from_lines( 6504 qf_info_T *qi, 6505 int qf_idx, 6506 dict_T *what, 6507 dictitem_T *di, 6508 int action) 6509 { 6510 char_u *errorformat = p_efm; 6511 dictitem_T *efm_di; 6512 int retval = FAIL; 6513 6514 // Use the user supplied errorformat settings (if present) 6515 if ((efm_di = dict_find(what, (char_u *)"efm", -1)) != NULL) 6516 { 6517 if (efm_di->di_tv.v_type != VAR_STRING || 6518 efm_di->di_tv.vval.v_string == NULL) 6519 return FAIL; 6520 errorformat = efm_di->di_tv.vval.v_string; 6521 } 6522 6523 // Only a List value is supported 6524 if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL) 6525 return FAIL; 6526 6527 if (action == 'r') 6528 qf_free_items(&qi->qf_lists[qf_idx]); 6529 if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat, 6530 FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0) 6531 retval = OK; 6532 6533 return retval; 6534 } 6535 6536 /* 6537 * Set quickfix list context. 6538 */ 6539 static int 6540 qf_setprop_context(qf_list_T *qfl, dictitem_T *di) 6541 { 6542 typval_T *ctx; 6543 6544 free_tv(qfl->qf_ctx); 6545 ctx = alloc_tv(); 6546 if (ctx != NULL) 6547 copy_tv(&di->di_tv, ctx); 6548 qfl->qf_ctx = ctx; 6549 6550 return OK; 6551 } 6552 6553 /* 6554 * Set the current index in the specified quickfix list 6555 */ 6556 static int 6557 qf_setprop_curidx(qf_info_T *qi, qf_list_T *qfl, dictitem_T *di) 6558 { 6559 int denote = FALSE; 6560 int newidx; 6561 int old_qfidx; 6562 qfline_T *qf_ptr; 6563 6564 // If the specified index is '$', then use the last entry 6565 if (di->di_tv.v_type == VAR_STRING 6566 && di->di_tv.vval.v_string != NULL 6567 && STRCMP(di->di_tv.vval.v_string, "$") == 0) 6568 newidx = qfl->qf_count; 6569 else 6570 { 6571 // Otherwise use the specified index 6572 newidx = tv_get_number_chk(&di->di_tv, &denote); 6573 if (denote) 6574 return FAIL; 6575 } 6576 6577 if (newidx < 1) // sanity check 6578 return FAIL; 6579 if (newidx > qfl->qf_count) 6580 newidx = qfl->qf_count; 6581 6582 old_qfidx = qfl->qf_index; 6583 qf_ptr = get_nth_entry(qfl, newidx, &newidx); 6584 if (qf_ptr == NULL) 6585 return FAIL; 6586 qfl->qf_ptr = qf_ptr; 6587 qfl->qf_index = newidx; 6588 6589 // If the current list is modified and it is displayed in the quickfix 6590 // window, then Update it. 6591 if (qi->qf_lists[qi->qf_curlist].qf_id == qfl->qf_id) 6592 qf_win_pos_update(qi, old_qfidx); 6593 6594 return OK; 6595 } 6596 6597 /* 6598 * Set quickfix/location list properties (title, items, context). 6599 * Also used to add items from parsing a list of lines. 6600 * Used by the setqflist() and setloclist() Vim script functions. 6601 */ 6602 static int 6603 qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) 6604 { 6605 dictitem_T *di; 6606 int retval = FAIL; 6607 int qf_idx; 6608 int newlist = FALSE; 6609 qf_list_T *qfl; 6610 6611 if (action == ' ' || qf_stack_empty(qi)) 6612 newlist = TRUE; 6613 6614 qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist); 6615 if (qf_idx == INVALID_QFIDX) // List not found 6616 return FAIL; 6617 6618 if (newlist) 6619 { 6620 qi->qf_curlist = qf_idx; 6621 qf_new_list(qi, title); 6622 qf_idx = qi->qf_curlist; 6623 } 6624 6625 qfl = &qi->qf_lists[qf_idx]; 6626 if ((di = dict_find(what, (char_u *)"title", -1)) != NULL) 6627 retval = qf_setprop_title(qi, qf_idx, what, di); 6628 if ((di = dict_find(what, (char_u *)"items", -1)) != NULL) 6629 retval = qf_setprop_items(qi, qf_idx, di, action); 6630 if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) 6631 retval = qf_setprop_items_from_lines(qi, qf_idx, what, di, action); 6632 if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) 6633 retval = qf_setprop_context(qfl, di); 6634 if ((di = dict_find(what, (char_u *)"idx", -1)) != NULL) 6635 retval = qf_setprop_curidx(qi, qfl, di); 6636 6637 if (retval == OK) 6638 qf_list_changed(qfl); 6639 6640 return retval; 6641 } 6642 6643 /* 6644 * Free the entire quickfix/location list stack. 6645 * If the quickfix/location list window is open, then clear it. 6646 */ 6647 static void 6648 qf_free_stack(win_T *wp, qf_info_T *qi) 6649 { 6650 win_T *qfwin = qf_find_win(qi); 6651 win_T *llwin = NULL; 6652 6653 if (qfwin != NULL) 6654 { 6655 // If the quickfix/location list window is open, then clear it 6656 if (qi->qf_curlist < qi->qf_listcount) 6657 qf_free(&qi->qf_lists[qi->qf_curlist]); 6658 qf_update_buffer(qi, NULL); 6659 } 6660 6661 if (wp != NULL && IS_LL_WINDOW(wp)) 6662 { 6663 // If in the location list window, then use the non-location list 6664 // window with this location list (if present) 6665 llwin = qf_find_win_with_loclist(qi); 6666 if (llwin != NULL) 6667 wp = llwin; 6668 } 6669 6670 qf_free_all(wp); 6671 if (wp == NULL) 6672 { 6673 // quickfix list 6674 qi->qf_curlist = 0; 6675 qi->qf_listcount = 0; 6676 } 6677 else if (qfwin != NULL) 6678 { 6679 // If the location list window is open, then create a new empty 6680 // location list 6681 qf_info_T *new_ll = qf_alloc_stack(QFLT_LOCATION); 6682 new_ll->qf_bufnr = qfwin->w_buffer->b_fnum; 6683 6684 // first free the list reference in the location list window 6685 ll_free_all(&qfwin->w_llist_ref); 6686 6687 qfwin->w_llist_ref = new_ll; 6688 if (wp != qfwin) 6689 { 6690 wp->w_llist = new_ll; 6691 new_ll->qf_refcount++; 6692 } 6693 } 6694 } 6695 6696 /* 6697 * Populate the quickfix list with the items supplied in the list 6698 * of dictionaries. "title" will be copied to w:quickfix_title. 6699 * "action" is 'a' for add, 'r' for replace. Otherwise create a new list. 6700 */ 6701 int 6702 set_errorlist( 6703 win_T *wp, 6704 list_T *list, 6705 int action, 6706 char_u *title, 6707 dict_T *what) 6708 { 6709 qf_info_T *qi = &ql_info; 6710 int retval = OK; 6711 6712 if (wp != NULL) 6713 { 6714 qi = ll_get_or_alloc_list(wp); 6715 if (qi == NULL) 6716 return FAIL; 6717 } 6718 6719 if (action == 'f') 6720 { 6721 // Free the entire quickfix or location list stack 6722 qf_free_stack(wp, qi); 6723 return OK; 6724 } 6725 6726 incr_quickfix_busy(); 6727 6728 if (what != NULL) 6729 retval = qf_set_properties(qi, what, action, title); 6730 else 6731 { 6732 retval = qf_add_entries(qi, qi->qf_curlist, list, title, action); 6733 if (retval == OK) 6734 qf_list_changed(&qi->qf_lists[qi->qf_curlist]); 6735 } 6736 6737 decr_quickfix_busy(); 6738 6739 return retval; 6740 } 6741 6742 /* 6743 * Mark the context as in use for all the lists in a quickfix stack. 6744 */ 6745 static int 6746 mark_quickfix_ctx(qf_info_T *qi, int copyID) 6747 { 6748 int i; 6749 int abort = FALSE; 6750 typval_T *ctx; 6751 6752 for (i = 0; i < LISTCOUNT && !abort; ++i) 6753 { 6754 ctx = qi->qf_lists[i].qf_ctx; 6755 if (ctx != NULL && ctx->v_type != VAR_NUMBER 6756 && ctx->v_type != VAR_STRING && ctx->v_type != VAR_FLOAT) 6757 abort = set_ref_in_item(ctx, copyID, NULL, NULL); 6758 } 6759 6760 return abort; 6761 } 6762 6763 /* 6764 * Mark the context of the quickfix list and the location lists (if present) as 6765 * "in use". So that garbage collection doesn't free the context. 6766 */ 6767 int 6768 set_ref_in_quickfix(int copyID) 6769 { 6770 int abort = FALSE; 6771 tabpage_T *tp; 6772 win_T *win; 6773 6774 abort = mark_quickfix_ctx(&ql_info, copyID); 6775 if (abort) 6776 return abort; 6777 6778 FOR_ALL_TAB_WINDOWS(tp, win) 6779 { 6780 if (win->w_llist != NULL) 6781 { 6782 abort = mark_quickfix_ctx(win->w_llist, copyID); 6783 if (abort) 6784 return abort; 6785 } 6786 if (IS_LL_WINDOW(win) && (win->w_llist_ref->qf_refcount == 1)) 6787 { 6788 // In a location list window and none of the other windows is 6789 // referring to this location list. Mark the location list 6790 // context as still in use. 6791 abort = mark_quickfix_ctx(win->w_llist_ref, copyID); 6792 if (abort) 6793 return abort; 6794 } 6795 } 6796 6797 return abort; 6798 } 6799 #endif 6800 6801 /* 6802 * ":[range]cbuffer [bufnr]" command. 6803 * ":[range]caddbuffer [bufnr]" command. 6804 * ":[range]cgetbuffer [bufnr]" command. 6805 * ":[range]lbuffer [bufnr]" command. 6806 * ":[range]laddbuffer [bufnr]" command. 6807 * ":[range]lgetbuffer [bufnr]" command. 6808 */ 6809 void 6810 ex_cbuffer(exarg_T *eap) 6811 { 6812 buf_T *buf = NULL; 6813 qf_info_T *qi = &ql_info; 6814 char_u *au_name = NULL; 6815 int res; 6816 int_u save_qfid; 6817 win_T *wp = NULL; 6818 6819 switch (eap->cmdidx) 6820 { 6821 case CMD_cbuffer: au_name = (char_u *)"cbuffer"; break; 6822 case CMD_cgetbuffer: au_name = (char_u *)"cgetbuffer"; break; 6823 case CMD_caddbuffer: au_name = (char_u *)"caddbuffer"; break; 6824 case CMD_lbuffer: au_name = (char_u *)"lbuffer"; break; 6825 case CMD_lgetbuffer: au_name = (char_u *)"lgetbuffer"; break; 6826 case CMD_laddbuffer: au_name = (char_u *)"laddbuffer"; break; 6827 default: break; 6828 } 6829 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, 6830 curbuf->b_fname, TRUE, curbuf)) 6831 { 6832 #ifdef FEAT_EVAL 6833 if (aborting()) 6834 return; 6835 #endif 6836 } 6837 6838 // Must come after autocommands. 6839 if (is_loclist_cmd(eap->cmdidx)) 6840 { 6841 qi = ll_get_or_alloc_list(curwin); 6842 if (qi == NULL) 6843 return; 6844 wp = curwin; 6845 } 6846 6847 if (*eap->arg == NUL) 6848 buf = curbuf; 6849 else if (*skipwhite(skipdigits(eap->arg)) == NUL) 6850 buf = buflist_findnr(atoi((char *)eap->arg)); 6851 if (buf == NULL) 6852 emsg(_(e_invarg)); 6853 else if (buf->b_ml.ml_mfp == NULL) 6854 emsg(_("E681: Buffer is not loaded")); 6855 else 6856 { 6857 if (eap->addr_count == 0) 6858 { 6859 eap->line1 = 1; 6860 eap->line2 = buf->b_ml.ml_line_count; 6861 } 6862 if (eap->line1 < 1 || eap->line1 > buf->b_ml.ml_line_count 6863 || eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count) 6864 emsg(_(e_invrange)); 6865 else 6866 { 6867 char_u *qf_title = qf_cmdtitle(*eap->cmdlinep); 6868 6869 if (buf->b_sfname) 6870 { 6871 vim_snprintf((char *)IObuff, IOSIZE, "%s (%s)", 6872 (char *)qf_title, (char *)buf->b_sfname); 6873 qf_title = IObuff; 6874 } 6875 6876 incr_quickfix_busy(); 6877 6878 res = qf_init_ext(qi, qi->qf_curlist, NULL, buf, NULL, p_efm, 6879 (eap->cmdidx != CMD_caddbuffer 6880 && eap->cmdidx != CMD_laddbuffer), 6881 eap->line1, eap->line2, 6882 qf_title, NULL); 6883 if (qf_stack_empty(qi)) 6884 { 6885 decr_quickfix_busy(); 6886 return; 6887 } 6888 if (res >= 0) 6889 qf_list_changed(&qi->qf_lists[qi->qf_curlist]); 6890 6891 // Remember the current quickfix list identifier, so that we can 6892 // check for autocommands changing the current quickfix list. 6893 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 6894 if (au_name != NULL) 6895 { 6896 buf_T *curbuf_old = curbuf; 6897 6898 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, 6899 curbuf->b_fname, TRUE, curbuf); 6900 if (curbuf != curbuf_old) 6901 // Autocommands changed buffer, don't jump now, "qi" may 6902 // be invalid. 6903 res = 0; 6904 } 6905 // Jump to the first error for a new list and if autocmds didn't 6906 // free the list. 6907 if (res > 0 && (eap->cmdidx == CMD_cbuffer || 6908 eap->cmdidx == CMD_lbuffer) 6909 && qflist_valid(wp, save_qfid)) 6910 // display the first error 6911 qf_jump_first(qi, save_qfid, eap->forceit); 6912 6913 decr_quickfix_busy(); 6914 } 6915 } 6916 } 6917 6918 #if defined(FEAT_EVAL) || defined(PROTO) 6919 /* 6920 * ":cexpr {expr}", ":cgetexpr {expr}", ":caddexpr {expr}" command. 6921 * ":lexpr {expr}", ":lgetexpr {expr}", ":laddexpr {expr}" command. 6922 */ 6923 void 6924 ex_cexpr(exarg_T *eap) 6925 { 6926 typval_T *tv; 6927 qf_info_T *qi = &ql_info; 6928 char_u *au_name = NULL; 6929 int res; 6930 int_u save_qfid; 6931 win_T *wp = NULL; 6932 6933 switch (eap->cmdidx) 6934 { 6935 case CMD_cexpr: au_name = (char_u *)"cexpr"; break; 6936 case CMD_cgetexpr: au_name = (char_u *)"cgetexpr"; break; 6937 case CMD_caddexpr: au_name = (char_u *)"caddexpr"; break; 6938 case CMD_lexpr: au_name = (char_u *)"lexpr"; break; 6939 case CMD_lgetexpr: au_name = (char_u *)"lgetexpr"; break; 6940 case CMD_laddexpr: au_name = (char_u *)"laddexpr"; break; 6941 default: break; 6942 } 6943 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, 6944 curbuf->b_fname, TRUE, curbuf)) 6945 { 6946 #ifdef FEAT_EVAL 6947 if (aborting()) 6948 return; 6949 #endif 6950 } 6951 6952 if (is_loclist_cmd(eap->cmdidx)) 6953 { 6954 qi = ll_get_or_alloc_list(curwin); 6955 if (qi == NULL) 6956 return; 6957 wp = curwin; 6958 } 6959 6960 // Evaluate the expression. When the result is a string or a list we can 6961 // use it to fill the errorlist. 6962 tv = eval_expr(eap->arg, NULL); 6963 if (tv != NULL) 6964 { 6965 if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL) 6966 || (tv->v_type == VAR_LIST && tv->vval.v_list != NULL)) 6967 { 6968 incr_quickfix_busy(); 6969 res = qf_init_ext(qi, qi->qf_curlist, NULL, NULL, tv, p_efm, 6970 (eap->cmdidx != CMD_caddexpr 6971 && eap->cmdidx != CMD_laddexpr), 6972 (linenr_T)0, (linenr_T)0, 6973 qf_cmdtitle(*eap->cmdlinep), NULL); 6974 if (qf_stack_empty(qi)) 6975 { 6976 decr_quickfix_busy(); 6977 goto cleanup; 6978 } 6979 if (res >= 0) 6980 qf_list_changed(&qi->qf_lists[qi->qf_curlist]); 6981 6982 // Remember the current quickfix list identifier, so that we can 6983 // check for autocommands changing the current quickfix list. 6984 save_qfid = qi->qf_lists[qi->qf_curlist].qf_id; 6985 if (au_name != NULL) 6986 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, 6987 curbuf->b_fname, TRUE, curbuf); 6988 6989 // Jump to the first error for a new list and if autocmds didn't 6990 // free the list. 6991 if (res > 0 && (eap->cmdidx == CMD_cexpr 6992 || eap->cmdidx == CMD_lexpr) 6993 && qflist_valid(wp, save_qfid)) 6994 // display the first error 6995 qf_jump_first(qi, save_qfid, eap->forceit); 6996 decr_quickfix_busy(); 6997 } 6998 else 6999 emsg(_("E777: String or List expected")); 7000 cleanup: 7001 free_tv(tv); 7002 } 7003 } 7004 #endif 7005 7006 /* 7007 * Get the location list for ":lhelpgrep" 7008 */ 7009 static qf_info_T * 7010 hgr_get_ll(int *new_ll) 7011 { 7012 win_T *wp; 7013 qf_info_T *qi; 7014 7015 // If the current window is a help window, then use it 7016 if (bt_help(curwin->w_buffer)) 7017 wp = curwin; 7018 else 7019 // Find an existing help window 7020 wp = qf_find_help_win(); 7021 7022 if (wp == NULL) // Help window not found 7023 qi = NULL; 7024 else 7025 qi = wp->w_llist; 7026 7027 if (qi == NULL) 7028 { 7029 // Allocate a new location list for help text matches 7030 if ((qi = qf_alloc_stack(QFLT_LOCATION)) == NULL) 7031 return NULL; 7032 *new_ll = TRUE; 7033 } 7034 7035 return qi; 7036 } 7037 7038 /* 7039 * Search for a pattern in a help file. 7040 */ 7041 static void 7042 hgr_search_file( 7043 qf_info_T *qi, 7044 char_u *fname, 7045 vimconv_T *p_vc, 7046 regmatch_T *p_regmatch) 7047 { 7048 FILE *fd; 7049 long lnum; 7050 7051 fd = mch_fopen((char *)fname, "r"); 7052 if (fd == NULL) 7053 return; 7054 7055 lnum = 1; 7056 while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) 7057 { 7058 char_u *line = IObuff; 7059 7060 // Convert a line if 'encoding' is not utf-8 and 7061 // the line contains a non-ASCII character. 7062 if (p_vc->vc_type != CONV_NONE 7063 && has_non_ascii(IObuff)) 7064 { 7065 line = string_convert(p_vc, IObuff, NULL); 7066 if (line == NULL) 7067 line = IObuff; 7068 } 7069 7070 if (vim_regexec(p_regmatch, line, (colnr_T)0)) 7071 { 7072 int l = (int)STRLEN(line); 7073 7074 // remove trailing CR, LF, spaces, etc. 7075 while (l > 0 && line[l - 1] <= ' ') 7076 line[--l] = NUL; 7077 7078 if (qf_add_entry(qi, 7079 qi->qf_curlist, 7080 NULL, // dir 7081 fname, 7082 NULL, 7083 0, 7084 line, 7085 lnum, 7086 (int)(p_regmatch->startp[0] - line) 7087 + 1, // col 7088 FALSE, // vis_col 7089 NULL, // search pattern 7090 0, // nr 7091 1, // type 7092 TRUE // valid 7093 ) == FAIL) 7094 { 7095 got_int = TRUE; 7096 if (line != IObuff) 7097 vim_free(line); 7098 break; 7099 } 7100 } 7101 if (line != IObuff) 7102 vim_free(line); 7103 ++lnum; 7104 line_breakcheck(); 7105 } 7106 fclose(fd); 7107 } 7108 7109 /* 7110 * Search for a pattern in all the help files in the doc directory under 7111 * the given directory. 7112 */ 7113 static void 7114 hgr_search_files_in_dir( 7115 qf_info_T *qi, 7116 char_u *dirname, 7117 regmatch_T *p_regmatch, 7118 vimconv_T *p_vc 7119 #ifdef FEAT_MULTI_LANG 7120 , char_u *lang 7121 #endif 7122 ) 7123 { 7124 int fcount; 7125 char_u **fnames; 7126 int fi; 7127 7128 // Find all "*.txt" and "*.??x" files in the "doc" directory. 7129 add_pathsep(dirname); 7130 STRCAT(dirname, "doc/*.\\(txt\\|??x\\)"); 7131 if (gen_expand_wildcards(1, &dirname, &fcount, 7132 &fnames, EW_FILE|EW_SILENT) == OK 7133 && fcount > 0) 7134 { 7135 for (fi = 0; fi < fcount && !got_int; ++fi) 7136 { 7137 #ifdef FEAT_MULTI_LANG 7138 // Skip files for a different language. 7139 if (lang != NULL 7140 && STRNICMP(lang, fnames[fi] 7141 + STRLEN(fnames[fi]) - 3, 2) != 0 7142 && !(STRNICMP(lang, "en", 2) == 0 7143 && STRNICMP("txt", fnames[fi] 7144 + STRLEN(fnames[fi]) - 3, 3) == 0)) 7145 continue; 7146 #endif 7147 7148 hgr_search_file(qi, fnames[fi], p_vc, p_regmatch); 7149 } 7150 FreeWild(fcount, fnames); 7151 } 7152 } 7153 7154 /* 7155 * Search for a pattern in all the help files in the 'runtimepath' 7156 * and add the matches to a quickfix list. 7157 * 'lang' is the language specifier. If supplied, then only matches in the 7158 * specified language are found. 7159 */ 7160 static void 7161 hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *lang) 7162 { 7163 char_u *p; 7164 7165 vimconv_T vc; 7166 7167 // Help files are in utf-8 or latin1, convert lines when 'encoding' 7168 // differs. 7169 vc.vc_type = CONV_NONE; 7170 if (!enc_utf8) 7171 convert_setup(&vc, (char_u *)"utf-8", p_enc); 7172 7173 // Go through all the directories in 'runtimepath' 7174 p = p_rtp; 7175 while (*p != NUL && !got_int) 7176 { 7177 copy_option_part(&p, NameBuff, MAXPATHL, ","); 7178 7179 hgr_search_files_in_dir(qi, NameBuff, p_regmatch, &vc 7180 #ifdef FEAT_MULTI_LANG 7181 , lang 7182 #endif 7183 ); 7184 } 7185 7186 if (vc.vc_type != CONV_NONE) 7187 convert_setup(&vc, NULL, NULL); 7188 } 7189 7190 /* 7191 * ":helpgrep {pattern}" 7192 */ 7193 void 7194 ex_helpgrep(exarg_T *eap) 7195 { 7196 regmatch_T regmatch; 7197 char_u *save_cpo; 7198 qf_info_T *qi = &ql_info; 7199 int new_qi = FALSE; 7200 char_u *au_name = NULL; 7201 char_u *lang = NULL; 7202 7203 switch (eap->cmdidx) 7204 { 7205 case CMD_helpgrep: au_name = (char_u *)"helpgrep"; break; 7206 case CMD_lhelpgrep: au_name = (char_u *)"lhelpgrep"; break; 7207 default: break; 7208 } 7209 if (au_name != NULL && apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, 7210 curbuf->b_fname, TRUE, curbuf)) 7211 { 7212 #ifdef FEAT_EVAL 7213 if (aborting()) 7214 return; 7215 #endif 7216 } 7217 7218 // Make 'cpoptions' empty, the 'l' flag should not be used here. 7219 save_cpo = p_cpo; 7220 p_cpo = empty_option; 7221 7222 if (is_loclist_cmd(eap->cmdidx)) 7223 { 7224 qi = hgr_get_ll(&new_qi); 7225 if (qi == NULL) 7226 return; 7227 } 7228 7229 incr_quickfix_busy(); 7230 7231 #ifdef FEAT_MULTI_LANG 7232 // Check for a specified language 7233 lang = check_help_lang(eap->arg); 7234 #endif 7235 regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING); 7236 regmatch.rm_ic = FALSE; 7237 if (regmatch.regprog != NULL) 7238 { 7239 qf_list_T *qfl; 7240 7241 // create a new quickfix list 7242 qf_new_list(qi, qf_cmdtitle(*eap->cmdlinep)); 7243 7244 hgr_search_in_rtp(qi, ®match, lang); 7245 7246 vim_regfree(regmatch.regprog); 7247 7248 qfl = &qi->qf_lists[qi->qf_curlist]; 7249 qfl->qf_nonevalid = FALSE; 7250 qfl->qf_ptr = qfl->qf_start; 7251 qfl->qf_index = 1; 7252 qf_list_changed(qfl); 7253 qf_update_buffer(qi, NULL); 7254 } 7255 7256 if (p_cpo == empty_option) 7257 p_cpo = save_cpo; 7258 else 7259 // Darn, some plugin changed the value. 7260 free_string_option(save_cpo); 7261 7262 if (au_name != NULL) 7263 { 7264 apply_autocmds(EVENT_QUICKFIXCMDPOST, au_name, 7265 curbuf->b_fname, TRUE, curbuf); 7266 if (!new_qi && IS_LL_STACK(qi) && qf_find_buf(qi) == NULL) 7267 { 7268 // autocommands made "qi" invalid 7269 decr_quickfix_busy(); 7270 return; 7271 } 7272 } 7273 7274 // Jump to first match. 7275 if (!qf_list_empty(qi, qi->qf_curlist)) 7276 qf_jump(qi, 0, 0, FALSE); 7277 else 7278 semsg(_(e_nomatch2), eap->arg); 7279 7280 decr_quickfix_busy(); 7281 7282 if (eap->cmdidx == CMD_lhelpgrep) 7283 { 7284 // If the help window is not opened or if it already points to the 7285 // correct location list, then free the new location list. 7286 if (!bt_help(curwin->w_buffer) || curwin->w_llist == qi) 7287 { 7288 if (new_qi) 7289 ll_free_all(&qi); 7290 } 7291 else if (curwin->w_llist == NULL) 7292 curwin->w_llist = qi; 7293 } 7294 } 7295 7296 #endif /* FEAT_QUICKFIX */ 7297