Skip to content

Commit a2aa8a2

Browse files
committed
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)
1 parent 4e601e3 commit a2aa8a2

3 files changed

Lines changed: 162 additions & 92 deletions

File tree

src/quickfix.c

Lines changed: 154 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct qfline_S
4646
* There is a stack of error lists.
4747
*/
4848
#define LISTCOUNT 10
49+
#define INVALID_QFIDX (-1)
4950

5051
/*
5152
* Quickfix/Location list definition
@@ -5085,7 +5086,7 @@ qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
50855086
{
50865087
qf_idx = di->di_tv.vval.v_number - 1;
50875088
if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
5088-
qf_idx = -1;
5089+
qf_idx = INVALID_QFIDX;
50895090
}
50905091
}
50915092
else if (di->di_tv.v_type == VAR_STRING
@@ -5094,7 +5095,7 @@ qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
50945095
/* Get the last quickfix list number */
50955096
qf_idx = qi->qf_listcount - 1;
50965097
else
5097-
qf_idx = -1;
5098+
qf_idx = INVALID_QFIDX;
50985099
}
50995100

51005101
if ((di = dict_find(what, (char_u *)"id", -1)) != NULL)
@@ -5109,7 +5110,7 @@ qf_getprop_qfidx(qf_info_T *qi, dict_T *what)
51095110
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
51105111
}
51115112
else
5112-
qf_idx = -1;
5113+
qf_idx = INVALID_QFIDX;
51135114
}
51145115

51155116
return qf_idx;
@@ -5251,7 +5252,7 @@ qf_get_properties(win_T *wp, dict_T *what, dict_T *retdict)
52515252
qf_idx = qf_getprop_qfidx(qi, what);
52525253

52535254
/* 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)
52555256
return qf_getprop_defaults(qi, flags, retdict);
52565257

52575258
if (flags & QF_GETLIST_TITLE)
@@ -5405,19 +5406,19 @@ qf_add_entries(
54055406
return retval;
54065407
}
54075408

5409+
/*
5410+
* Get the quickfix list index from 'nr' or 'id'
5411+
*/
54085412
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)
54105418
{
54115419
dictitem_T *di;
5412-
int retval = FAIL;
5413-
int qf_idx;
5414-
int newlist = FALSE;
5415-
char_u *errorformat = p_efm;
5420+
int qf_idx = qi->qf_curlist; /* default is the current list */
54165421

5417-
if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
5418-
newlist = TRUE;
5419-
5420-
qf_idx = qi->qf_curlist; /* default is the current list */
54215422
if ((di = dict_find(what, (char_u *)"nr", -1)) != NULL)
54225423
{
54235424
/* Use the specified quickfix/location list */
@@ -5434,118 +5435,179 @@ qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title)
54345435
* non-available list and add the new list at the end of the
54355436
* stack.
54365437
*/
5437-
newlist = TRUE;
5438-
qf_idx = qi->qf_listcount - 1;
5438+
*newlist = TRUE;
5439+
qf_idx = qi->qf_listcount > 0 ? qi->qf_listcount - 1 : 0;
54395440
}
54405441
else if (qf_idx < 0 || qf_idx >= qi->qf_listcount)
5441-
return FAIL;
5442+
return INVALID_QFIDX;
54425443
else if (action != ' ')
5443-
newlist = FALSE; /* use the specified list */
5444+
*newlist = FALSE; /* use the specified list */
54445445
}
54455446
else if (di->di_tv.v_type == VAR_STRING
5446-
&& di->di_tv.vval.v_string != NULL
5447-
&& STRCMP(di->di_tv.vval.v_string, "$") == 0)
5447+
&& di->di_tv.vval.v_string != NULL
5448+
&& STRCMP(di->di_tv.vval.v_string, "$") == 0)
54485449
{
54495450
if (qi->qf_listcount > 0)
54505451
qf_idx = qi->qf_listcount - 1;
5451-
else if (newlist)
5452+
else if (*newlist)
54525453
qf_idx = 0;
54535454
else
5454-
return FAIL;
5455+
return INVALID_QFIDX;
54555456
}
54565457
else
5457-
return FAIL;
5458+
return INVALID_QFIDX;
54585459
}
54595460

5460-
if (!newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
5461+
if (!*newlist && (di = dict_find(what, (char_u *)"id", -1)) != NULL)
54615462
{
54625463
/* Use the quickfix/location list with the specified id */
5463-
if (di->di_tv.v_type == VAR_NUMBER)
5464-
{
5465-
qf_idx = qf_id2nr(qi, di->di_tv.vval.v_number);
5466-
if (qf_idx == -1)
5467-
return FAIL; /* List not found */
5468-
}
5469-
else
5470-
return FAIL;
5471-
}
5464+
if (di->di_tv.v_type != VAR_NUMBER)
5465+
return INVALID_QFIDX;
54725466

5473-
if (newlist)
5474-
{
5475-
qi->qf_curlist = qf_idx;
5476-
qf_new_list(qi, title);
5477-
qf_idx = qi->qf_curlist;
5467+
return qf_id2nr(qi, di->di_tv.vval.v_number);
54785468
}
54795469

5480-
if ((di = dict_find(what, (char_u *)"title", -1)) != NULL)
5481-
{
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-
}
5470+
return qf_idx;
5471+
}
54925472

5493-
if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
5494-
{
5495-
if (di->di_tv.v_type == VAR_LIST)
5496-
{
5497-
char_u *title_save = vim_strsave(qi->qf_lists[qf_idx].qf_title);
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;
54985481

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-
}
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;
55145499

5515-
if ((di = dict_find(what, (char_u *)"efm", -1)) != NULL)
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')
55165507
{
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;
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);
55205515
}
5516+
vim_free(title_save);
55215517

5522-
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
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)
55235538
{
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
5539+
if (efm_di->di_tv.v_type != VAR_STRING ||
5540+
efm_di->di_tv.vval.v_string == NULL)
55345541
return FAIL;
5542+
errorformat = efm_di->di_tv.vval.v_string;
55355543
}
55365544

5537-
if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
5538-
{
5539-
typval_T *ctx;
5545+
/* Only a List value is supported */
5546+
if (di->di_tv.v_type != VAR_LIST || di->di_tv.vval.v_list == NULL)
5547+
return FAIL;
55405548

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;
5549+
if (action == 'r')
5550+
qf_free_items(qi, qf_idx);
5551+
if (qf_init_ext(qi, qf_idx, NULL, NULL, &di->di_tv, errorformat,
5552+
FALSE, (linenr_T)0, (linenr_T)0, NULL, NULL) > 0)
55465553
retval = OK;
5554+
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;
5594+
5595+
if (newlist)
5596+
{
5597+
qi->qf_curlist = qf_idx;
5598+
qf_new_list(qi, title);
5599+
qf_idx = qi->qf_curlist;
55475600
}
55485601

5602+
if ((di = dict_find(what, (char_u *)"title", -1)) != NULL)
5603+
retval = qf_setprop_title(qi, qf_idx, what, di);
5604+
if ((di = dict_find(what, (char_u *)"items", -1)) != NULL)
5605+
retval = qf_setprop_items(qi, qf_idx, di, action);
5606+
if ((di = dict_find(what, (char_u *)"lines", -1)) != NULL)
5607+
retval = qf_setprop_items_from_lines(qi, qf_idx, what, di, action);
5608+
if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
5609+
retval = qf_setprop_context(qi, qf_idx, di);
5610+
55495611
if (retval == OK)
55505612
qf_list_changed(qi, qf_idx);
55515613

src/testdir/test_quickfix.vim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,9 @@ func Xproperty_tests(cchar)
17951795
call assert_equal(0, s)
17961796
let d = g:Xgetlist({"title":1})
17971797
call assert_equal('Sample', d.title)
1798+
" Try setting title to a non-string value
1799+
call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
1800+
call assert_equal('Sample', g:Xgetlist({"title":1}).title)
17981801

17991802
Xopen
18001803
call assert_equal('Sample', w:quickfix_title)
@@ -1943,6 +1946,9 @@ func Xproperty_tests(cchar)
19431946
call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
19441947
call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
19451948

1949+
" Try setting the items using a string
1950+
call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
1951+
19461952
" Save and restore the quickfix stack
19471953
call g:Xsetlist([], 'f')
19481954
call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
1752,
764766
/**/
765767
1751,
766768
/**/

0 commit comments

Comments
 (0)