comparison src/quickfix.c @ 13760:aef8ba129a4f v8.0.1752

patch 8.0.1752: qf_set_properties() is to long commit https://github.com/vim/vim/commit/a2aa8a2b22de909619d7faa3ff5383a6224defc5 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Apr 24 13:55:00 2018 +0200 patch 8.0.1752: qf_set_properties() is to long Problem: qf_set_properties() is to long. Solution: Refactor the function. Define INVALID_QFIDX. (Yegappan Lakshmanan, closes #2812)
author Christian Brabandt <cb@256bit.org>
date Tue, 24 Apr 2018 14:00:07 +0200
parents c38f29387245
children 7bba231fdddc
comparison
equal deleted inserted replaced
13759:1cd810ca3658 13760:aef8ba129a4f
44 44
45 /* 45 /*
46 * There is a stack of error lists. 46 * There is a stack of error lists.
47 */ 47 */
48 #define LISTCOUNT 10 48 #define LISTCOUNT 10
49 #define INVALID_QFIDX (-1)
49 50
50 /* 51 /*
51 * Quickfix/Location list definition 52 * Quickfix/Location list definition
52 * Contains a list of entries (qfline_T). qf_start points to the first entry 53 * Contains a list of entries (qfline_T). qf_start points to the first entry
53 * and qf_last points to the last entry. qf_count contains the list size. 54 * and qf_last points to the last entry. qf_count contains the list size.
5083 /* for zero use the current list */ 5084 /* for zero use the current list */
5084 if (di->di_tv.vval.v_number != 0) 5085 if (di->di_tv.vval.v_number != 0)
5085 { 5086 {
5086 qf_idx = di->di_tv.vval.v_number - 1; 5087 qf_idx = di->di_tv.vval.v_number - 1;
5087 if (qf_idx < 0 || qf_idx >= qi->qf_listcount) 5088 if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
5088 qf_idx = -1; 5089 qf_idx = INVALID_QFIDX;
5089 } 5090 }
5090 } 5091 }
5091 else if (di->di_tv.v_type == VAR_STRING 5092 else if (di->di_tv.v_type == VAR_STRING
5092 && di->di_tv.vval.v_string != NULL 5093 && di->di_tv.vval.v_string != NULL
5093 && STRCMP(di->di_tv.vval.v_string, "$") == 0) 5094 && STRCMP(di->di_tv.vval.v_string, "$") == 0)
5094 /* Get the last quickfix list number */ 5095 /* Get the last quickfix list number */
5095 qf_idx = qi->qf_listcount - 1; 5096 qf_idx = qi->qf_listcount - 1;
5096 else 5097 else
5097 qf_idx = -1; 5098 qf_idx = INVALID_QFIDX;
5098 } 5099 }
5099 5100
5100 if ((di = dict_find(what, (char_u *)"id", -1)) != NULL) 5101 if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
5101 { 5102 {
5102 /* Look for a list with the specified id */ 5103 /* Look for a list with the specified id */
5107 */ 5108 */
5108 if (di->di_tv.vval.v_number != 0) 5109 if (di->di_tv.vval.v_number != 0)
5109 qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); 5110 qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
5110 } 5111 }
5111 else 5112 else
5112 qf_idx = -1; 5113 qf_idx = INVALID_QFIDX;
5113 } 5114 }
5114 5115
5115 return qf_idx; 5116 return qf_idx;
5116 } 5117 }
5117 5118
5249 5250
5250 if (qi != NULL && qi->qf_listcount != 0) 5251 if (qi != NULL && qi->qf_listcount != 0)
5251 qf_idx = qf_getprop_qfidx(qi, what); 5252 qf_idx = qf_getprop_qfidx(qi, what);
5252 5253
5253 /* List is not present or is empty */ 5254 /* List is not present or is empty */
5254 if (qi == NULL || qi->qf_listcount == 0 || qf_idx == -1) 5255 if (qi == NULL || qi->qf_listcount == 0 || qf_idx == INVALID_QFIDX)
5255 return qf_getprop_defaults(qi, flags, retdict); 5256 return qf_getprop_defaults(qi, flags, retdict);
5256 5257
5257 if (flags & QF_GETLIST_TITLE) 5258 if (flags & QF_GETLIST_TITLE)
5258 status = qf_getprop_title(qi, qf_idx, retdict); 5259 status = qf_getprop_title(qi, qf_idx, retdict);
5259 if ((status == OK) && (flags & QF_GETLIST_NR)) 5260 if ((status == OK) && (flags & QF_GETLIST_NR))
5403 qf_update_buffer(qi, old_last); 5404 qf_update_buffer(qi, old_last);
5404 5405
5405 return retval; 5406 return retval;
5406 } 5407 }
5407 5408
5409 /*
5410 * Get the quickfix list index from 'nr' or 'id'
5411 */
5408 static int 5412 static int
5409 qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) 5413 qf_setprop_get_qfidx(
5414 qf_info_T *qi,
5415 dict_T *what,
5416 int action,
5417 int *newlist)
5410 { 5418 {
5411 dictitem_T *di; 5419 dictitem_T *di;
5412 int retval = FAIL; 5420 int qf_idx = qi->qf_curlist; /* default is the current list */
5413 int qf_idx; 5421
5414 int newlist = FALSE;
5415 char_u *errorformat = p_efm;
5416
5417 if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
5418 newlist = TRUE;
5419
5420 qf_idx = qi->qf_curlist; /* default is the current list */
5421 if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL) 5422 if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
5422 { 5423 {
5423 /* Use the specified quickfix/location list */ 5424 /* Use the specified quickfix/location list */
5424 if (di->di_tv.v_type == VAR_NUMBER) 5425 if (di->di_tv.v_type == VAR_NUMBER)
5425 { 5426 {
5432 /* 5433 /*
5433 * When creating a new list, accept qf_idx pointing to the next 5434 * When creating a new list, accept qf_idx pointing to the next
5434 * non-available list and add the new list at the end of the 5435 * non-available list and add the new list at the end of the
5435 * stack. 5436 * stack.
5436 */ 5437 */
5437 newlist = TRUE; 5438 *newlist = TRUE;
5438 qf_idx = qi->qf_listcount - 1; 5439 qf_idx = qi->qf_listcount > 0 ? qi->qf_listcount - 1 : 0;
5439 } 5440 }
5440 else if (qf_idx < 0 || qf_idx >= qi->qf_listcount) 5441 else if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
5441 return FAIL; 5442 return INVALID_QFIDX;
5442 else if (action != ' ') 5443 else if (action != ' ')
5443 newlist = FALSE; /* use the specified list */ 5444 *newlist = FALSE; /* use the specified list */
5444 } 5445 }
5445 else if (di->di_tv.v_type == VAR_STRING 5446 else if (di->di_tv.v_type == VAR_STRING
5446 && di->di_tv.vval.v_string != NULL 5447 && di->di_tv.vval.v_string != NULL
5447 && STRCMP(di->di_tv.vval.v_string, "$") == 0) 5448 && STRCMP(di->di_tv.vval.v_string, "$") == 0)
5448 { 5449 {
5449 if (qi->qf_listcount > 0) 5450 if (qi->qf_listcount > 0)
5450 qf_idx = qi->qf_listcount - 1; 5451 qf_idx = qi->qf_listcount - 1;
5451 else if (newlist) 5452 else if (*newlist)
5452 qf_idx = 0; 5453 qf_idx = 0;
5453 else 5454 else
5454 return FAIL; 5455 return INVALID_QFIDX;
5455 } 5456 }
5456 else 5457 else
5458 return INVALID_QFIDX;
5459 }
5460
5461 if (!*newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
5462 {
5463 /* Use the quickfix/location list with the specified id */
5464 if (di->di_tv.v_type != VAR_NUMBER)
5465 return INVALID_QFIDX;
5466
5467 return qf_id2nr(qi, di->di_tv.vval.v_number);
5468 }
5469
5470 return qf_idx;
5471 }
5472
5473 /*
5474 * Set the quickfix list title.
5475 */
5476 static int
5477 qf_setprop_title(qf_info_T *qi, int qf_idx, dict_T *what, dictitem_T *di)
5478 {
5479 if (di->di_tv.v_type != VAR_STRING)
5480 return FAIL;
5481
5482 vim_free(qi->qf_lists[qf_idx].qf_title);
5483 qi->qf_lists[qf_idx].qf_title =
5484 get_dict_string(what, (char_u *)"title", TRUE);
5485 if (qf_idx == qi->qf_curlist)
5486 qf_update_win_titlevar(qi);
5487
5488 return OK;
5489 }
5490
5491 /*
5492 * Set quickfix list items/entries.
5493 */
5494 static int
5495 qf_setprop_items(qf_info_T *qi, int qf_idx, dictitem_T *di, int action)
5496 {
5497 int retval = FAIL;
5498 char_u *title_save;
5499
5500 if (di->di_tv.v_type != VAR_LIST)
5501 return FAIL;
5502
5503 title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
5504 retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
5505 title_save, action == ' ' ? 'a' : action);
5506 if (action == 'r')
5507 {
5508 /*
5509 * When replacing the quickfix list entries using
5510 * qf_add_entries(), the title is set with a ':' prefix.
5511 * Restore the title with the saved title.
5512 */
5513 vim_free(qi->qf_lists[qf_idx].qf_title);
5514 qi->qf_lists[qf_idx].qf_title = vim_strsave(title_save);
5515 }
5516 vim_free(title_save);
5517
5518 return retval;
5519 }
5520
5521 /*
5522 * Set quickfix list items/entries from a list of lines.
5523 */
5524 static int
5525 qf_setprop_items_from_lines(
5526 qf_info_T *qi,
5527 int qf_idx,
5528 dict_T *what,
5529 dictitem_T *di,
5530 int action)
5531 {
5532 char_u *errorformat = p_efm;
5533 dictitem_T *efm_di;
5534 int retval = FAIL;
5535
5536 /* Use the user supplied errorformat settings (if present) */
5537 if ((efm_di = dict_find(what, (char_u *)"efm", -1)) != NULL)
5538 {
5539 if (efm_di->di_tv.v_type != VAR_STRING ||
5540 efm_di->di_tv.vval.v_string == NULL)
5457 return FAIL; 5541 return FAIL;
5458 } 5542 errorformat = efm_di->di_tv.vval.v_string;
5459 5543 }
5460 if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL) 5544
5461 { 5545 /* Only a List value is supported */
5462 /* Use the quickfix/location list with the specified id */ 5546 if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL)
5463 if (di->di_tv.v_type == VAR_NUMBER) 5547 return FAIL;
5464 { 5548
5465 qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number); 5549 if (action == 'r')
5466 if (qf_idx == -1) 5550 qf_free_items(qi, qf_idx);
5467 return FAIL; /* List not found */ 5551 if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
5468 } 5552 FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
5469 else 5553 retval = OK;
5470 return FAIL; 5554
5471 } 5555 return retval;
5556 }
5557
5558 /*
5559 * Set quickfix list context.
5560 */
5561 static int
5562 qf_setprop_context(qf_info_T *qi, int qf_idx, dictitem_T *di)
5563 {
5564 typval_T *ctx;
5565
5566 free_tv(qi->qf_lists[qf_idx].qf_ctx);
5567 ctx = alloc_tv();
5568 if (ctx != NULL)
5569 copy_tv(&di->di_tv, ctx);
5570 qi->qf_lists[qf_idx].qf_ctx = ctx;
5571
5572 return OK;
5573 }
5574
5575 /*
5576 * Set quickfix/location list properties (title, items, context).
5577 * Also used to add items from parsing a list of lines.
5578 * Used by the setqflist() and setloclist() VimL functions.
5579 */
5580 static int
5581 qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
5582 {
5583 dictitem_T *di;
5584 int retval = FAIL;
5585 int qf_idx;
5586 int newlist = FALSE;
5587
5588 if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
5589 newlist = TRUE;
5590
5591 qf_idx = qf_setprop_get_qfidx(qi, what, action, &newlist);
5592 if (qf_idx == INVALID_QFIDX) /* List not found */
5593 return FAIL;
5472 5594
5473 if (newlist) 5595 if (newlist)
5474 { 5596 {
5475 qi->qf_curlist = qf_idx; 5597 qi->qf_curlist = qf_idx;
5476 qf_new_list(qi, title); 5598 qf_new_list(qi, title);
5477 qf_idx = qi->qf_curlist; 5599 qf_idx = qi->qf_curlist;
5478 } 5600 }
5479 5601
5480 if ((di = dict_find(what, (char_u *)"title", -1)) != NULL) 5602 if ((di = dict_find(what, (char_u *)"title", -1)) != NULL)
5481 { 5603 retval = qf_setprop_title(qi, qf_idx, what, di);
5482 if (di->di_tv.v_type == VAR_STRING)
5483 {
5484 vim_free(qi->qf_lists[qf_idx].qf_title);
5485 qi->qf_lists[qf_idx].qf_title =
5486 get_dict_string(what, (char_u *)"title", TRUE);
5487 if (qf_idx == qi->qf_curlist)
5488 qf_update_win_titlevar(qi);
5489 retval = OK;
5490 }
5491 }
5492
5493 if ((di = dict_find(what, (char_u *)"items", -1)) != NULL) 5604 if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
5494 { 5605 retval = qf_setprop_items(qi, qf_idx, di, action);
5495 if (di->di_tv.v_type == VAR_LIST)
5496 {
5497 char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
5498
5499 retval = qf_add_entries(qi, qf_idx, di->di_tv.vval.v_list,
5500 title_save, action == ' ' ? 'a' : action);
5501 if (action == 'r')
5502 {
5503 /*
5504 * When replacing the quickfix list entries using
5505 * qf_add_entries(), the title is set with a ':' prefix.
5506 * Restore the title with the saved title.
5507 */
5508 vim_free(qi->qf_lists[qf_idx].qf_title);
5509 qi->qf_lists[qf_idx].qf_title = vim_strsave(title_save);
5510 }
5511 vim_free(title_save);
5512 }
5513 }
5514
5515 if ((di = dict_find(what, (char_u *)"efm", -1)) != NULL)
5516 {
5517 if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL)
5518 return FAIL;
5519 errorformat = di->di_tv.vval.v_string;
5520 }
5521
5522 if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL) 5606 if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
5523 { 5607 retval = qf_setprop_items_from_lines(qi, qf_idx, what, di, action);
5524 /* Only a List value is supported */
5525 if (di->di_tv.v_type == VAR_LIST && di->di_tv.vval.v_list != NULL)
5526 {
5527 if (action == 'r')
5528 qf_free_items(qi, qf_idx);
5529 if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
5530 FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
5531 retval = OK;
5532 }
5533 else
5534 return FAIL;
5535 }
5536
5537 if ((di = dict_find(what, (char_u *)"context", -1)) != NULL) 5608 if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
5538 { 5609 retval = qf_setprop_context(qi, qf_idx, di);
5539 typval_T *ctx;
5540
5541 free_tv(qi->qf_lists[qf_idx].qf_ctx);
5542 ctx = alloc_tv();
5543 if (ctx != NULL)
5544 copy_tv(&di->di_tv, ctx);
5545 qi->qf_lists[qf_idx].qf_ctx = ctx;
5546 retval = OK;
5547 }
5548 5610
5549 if (retval == OK) 5611 if (retval == OK)
5550 qf_list_changed(qi, qf_idx); 5612 qf_list_changed(qi, qf_idx);
5551 5613
5552 return retval; 5614 return retval;